如何使用 useContext Hook 来共享状态

时间:2021-05-04 06:12:32

标签: javascript reactjs react-hooks

我有一个组件 ListItem

其中包含一个列表元素,单击时状态会发生变化

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

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

ChooseElements comp 中用于从数组创建列表
我想从状态为 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>
 
  );
}


我发现 useContext 可以在组件之间共享共享上下文值 但看起来上下文是在组件之外定义的,然后被组件所接受。 我可以用这个钩子实现我的请求吗?

1 个答案:

答案 0 :(得分:1)

正如这里对解决方案的评论中提到的,是将状态提升到父组件中。 ListItem 变成了一个“哑”组件,它只在状态保持在 ChooseElements 中时才使用它的 props:

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>
  );
}

Edit infallible-banzai-u1o7v