Sai Krishnadas
Sai Krishnadas

Reputation: 3409

How to set separate state for a mapped component in reactjs?

I have a component that is mapped and render from an array. That component has a state manage visibility (open and close). Setting a local state opens all the mapped components rather than the clicked one.

Code:

const App = () => {
  const dummyData = ["Select One", "Select Two", "Select Three"];
  const [visible, setVisible] = React.useState(false);
  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      {dummyData.map((data) => (
        <Popover
          visible={visible}
          onVisibleChange={(newVisible) => setVisible(newVisible)}
          content={
            <Select
              defaultValue="lucy"
              style={{
                width: 120
              }}
            >
              <Option value="jack">Jack</Option>
              <Option value="lucy">Lucy</Option>
            </Select>
          }
          title=""
          trigger="click"
        >
          <Button>{data}</Button>
        </Popover>
      ))}
    </div>
  );
};

On the above code, Popover is mapped from API response data.

Codesandbox link: https://codesandbox.io/s/three-ways-to-trigger-antd-4-21-6-forked-nxiph8?file=/demo.js

Upvotes: 0

Views: 601

Answers (1)

Aman Sadhwani
Aman Sadhwani

Reputation: 3658

Separate out state and re-use the component.

import React from "react";
import "antd/dist/antd.css";
import "./index.css";
import { Button, Popover, Select } from "antd";
const { Option } = Select;

const App = () => {
  const dummyData = ["Select One", "Select Two", "Select Three"];

  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      {dummyData.map((data) => (
        <RenderPopOver data={data} />
      ))}
    </div>
  );
};

export default App;

const RenderPopOver = ({ data }) => {
  const [visible, setVisible] = React.useState(false);
  return (
    <Popover
      visible={visible}
      onVisibleChange={(newVisible) => setVisible(newVisible)}
      content={
        <Select
          defaultValue="lucy"
          style={{
            width: 120
          }}
        >
          <Option value="jack">Jack</Option>
          <Option value="lucy">Lucy</Option>
        </Select>
      }
      title=""
      trigger="click"
    >
      <Button>{data}</Button>
    </Popover>
  );
};

Upvotes: 1

Related Questions