简体   繁体   中英

how to use useContext Hook for sharing States

i have a component ListItem

which contains a list element which state changes when clicked on

function ListItem(props) {
  const [isActive, setActive] = useState(false);

  console.log(isActive)
  return <li className={isActive ? 'selected': null}  onClick={(e)=> setActive(!isActive)}>{props.value}</li>;
}

Which is being used in the ChooseElements comp to create a list from an array
I want to retrieve the data from all list element which state is true


function ChooseElements() {
 
  const listItems = elementObjects.map((object) =>
  
    <ListItem key={object.id.toString()} value={object.Element} />
  );
  return (
    <div>   
    <ul>
      {listItems}
    </ul>

    <button onClick={listItems.forEach(element => { console.log(element)}) }>get Elements</button>
    {/*  with button click get all list items with specific class! */}
    </div>
 
  );
}


I have found the useContext to share share conext value between components but it looks like the the context is defined outside the components and then accecced by the components. Can I implement my request with this hook?

As mentioned in the comments to solution here is to lift the state up into the parent component. ListItem becomes a "dumb" component that only uses its props while the state is kept in ChooseElements :

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

const elementObjects = [
  { id: 1, Element: "element-1" },
  { id: 2, Element: "element-2" },
  { id: 3, Element: "element-3" },
  { id: 4, Element: "element-4" }
];

function ListItem({ isActive, toggleItem, value }) {
  return (
    <li className={isActive ? "selected" : null} onClick={toggleItem}>
      {value}
    </li>
  );
}

function ChooseElements() {
  const [activeItems, setActiveItems] = useState(new Set());

  const toggleItem = (id) => {
    const updatedItems = new Set(activeItems);
    if (updatedItems.has(id)) {
      updatedItems.delete(id);
    } else {
      updatedItems.add(id);
    }
    setActiveItems(updatedItems);
  };

  const listItems = elementObjects.map((object) => (
    <ListItem
      key={object.id.toString()}
      value={object.Element}
      isActive={activeItems.has(object.id)}
      toggleItem={() => toggleItem(object.id)}
    />
  ));

  return (
    <div>
      <ul>{listItems}</ul>

      <button
        onClick={() => {
          /*  with button click get all list items with specific class! */
          console.log(elementObjects.filter((o) => activeItems.has(o.id)));
        }}
      >
        get Elements
      </button>
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      <ChooseElements />
    </div>
  );
}

编辑 infallible-banzai-u1o7v

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM