0

I am working on a popup component where the parent component has the following code

import * as React from "react";
import "./styles.css";
import Popup from "./Popup";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Popup
        src="https://picsum.photos/200"
        alt="Fog"
        coreValue="Customer Focus"
      />
      <Popup
        src="https://picsum.photos/200/300?grayscale"
        alt="Grey Mountains"
        coreValue="Persistence"
      />
    </div>
  );
}

The child component should render a custom popup dependent on the props

import * as React from "react";
import { useState } from "react";

interface Props {
  src: string;
  alt: string;
  coreValue: string;
}

export default function Popup({ src, alt, coreValue }: Props): JSX.Element {
  const [customerFocus, setCustomerFocus] = useState(false);
  const [persistence, setPersistence] = useState(false);

  const toggleCustomerFocus = () => {
    setCustomerFocus(!customerFocus);
  };

  const togglePersistence = () => {
    setPersistence(!persistence);
  };

  const data = [
    {
      customerFocus: {
        title: "Dummy Title 1",
        content: "Dummy Content 1"
      },
      persistence: {
        title: "Dummy Title 2",
        content: "Dummy Content 2"
      }
    }
  ];
  return (
    <>
      <figure onClick={toggleCustomerFocus}>
        <img src={src} alt={alt} />
        <figcaption>{coreValue}</figcaption>
      </figure>
      {customerFocus && (
        <section>
          <h4>{data[0].customerFocus.title}</h4>
          <p>{data[0].customerFocus.content}</p>
          <button onClick={toggleCustomerFocus}>Close 1</button>
        </section>
      )}
      {persistence && (
        <section>
          <h4>{data[1].persistence.title}</h4>
          <p>{data[1].persistence.content}</p>
          <button onClick={togglePersistence}>Close 2</button>
        </section>
      )}
    </>
  );
}

Where <figure onClick={toggleCustomerFocus}>, I would like to pass a custom onClick function from the parent to its child so that the first popup renders Dummy Title 1 and Dummy Content 1 when clicked and the second popup renders Dummy Title 2 and Dummy Content 2 when clicked. As of now, both render the same popup when clicked.

How do I send a custom onClick function from the parent to child?

Codesandbox link

1
  • If you're using typescript, use react element instead of jsx element. This doesn't answer your question, but let me look into the issue. Commented Jan 1, 2021 at 3:32

1 Answer 1

2

While you could pass in state and setter from the parent App component, it doesn't make a lot of sense for your example.

I would try to keep the Popup component more generic.

In the example below the Popup component manages its own UI state (opened/closed), but all the content is passed in as props.

import React, { useState } from "react";
import "./styles.css";

const data = [
  {
    title: "Customer Focus title",
    content: "Customer Focus content",
    src: "https://picsum.photos/200",
    alt: "Fog",
    coreValue: "Customer Focus"
  },
  {
    title: "Persistence title",
    content: "Persistence content",
    src: "https://picsum.photos/200/300?grayscale",
    alt: "Grey Mountains",
    coreValue: "Persistence"
  }
];

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {data.map(({ title, content, src, alt, coreValue }) => (
        <Popup
          title={title}
          content={content}
          src={src}
          alt={alt}
          coreValue={coreValue}
        />
      ))}
    </div>
  );
}

interface Props {
  title: string;
  content: string;
  src: string;
  alt: string;
  coreValue: string;
}

function Popup({
  title = "",
  content = "",
  src = "",
  alt = "",
  coreValue = ""
}: Props) {
  const [showDetails, setShowDetails] = useState(false);

  return (
    <>
      <figure onClick={() => setShowDetails(true)}>
        <img src={src} alt={alt} />
        <figcaption>{coreValue}</figcaption>
      </figure>
      {showDetails && (
        <section>
          <h4>{title}</h4>
          <p>{content}</p>
          <button onClick={() => setShowDetails(false)}>Close 2</button>
        </section>
      )}
    </>
  );
}

Edit Popup (forked)

Sign up to request clarification or add additional context in comments.

2 Comments

For clarity, may I ask why props passed into the Popup are set to equal empty strings? Are these default values? Is it ok to remove them?
You're right. It's just the default value if the prop wasn't provided to the component. It's ok for you to remove them. See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.