我可以使用react中的useEffect挂钩从子级设置父级的状态

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我可以使用react中的useEffect挂钩从子级设置父级的状态相关的知识,希望对你有一定的参考价值。

我在子组件中有一组按钮,在单击时,将相应的状态值设置为true或false。我在这个子组件中也有一个useEffect钩子,它也依赖于所有这些状态值,因此,如果单击按钮,则此钩子会调用setFilter,它作为道具从父级传递下来...

const Filter = ( setFilter ) => 

  const [cycling, setCycling] = useState(true);
  const [diy, setDiy] = useState(true);

  useEffect(() => 
    setFilter(
      cycling: cycling,
      diy: diy
    );
  , [cycling, diy]);

  return (
    <Fragment>
      <Row>
        <Col>
          <Button block onClick=() => setCycling(!cycling)>cycling</Button>
        </Col>
        <Col>
          <Button block onClick=() => setdIY(!DIY)>DIY</Button>
        </Col>
      </Row>
    </Fragment>
  );
;

在父组件中,我显示项目列表。我在父级中有两种效果,一种是初始加载项目,另一种是在更改过滤器时触发。为了简洁起见,我删除了大多数代码,但我认为我的使用归结为以下事实:在渲染ItemDashboard时,过滤器被调用了两次。我该如何阻止这种情况的发生,或者我应该以其他方式看待这种情况。

const ItemDashboard = () => 

  const [filter, setFilter] = useState(null);

  useEffect(() => 
    console.log('on mount');
  , []);

  useEffect(() => 
    console.log('filter');
  , [filter]);

  return (
    <Container>..
      <Filter setFilter=setFilter />
    </Container>
  );

答案

是的,您可以,取决于状态的子组件中的useEffect也是您通常如何实现受控制和不受控制的组件的方式:

const NOOP = () => ;

// Filter
const Child = ( onChange = NOOP ) => 
  const [counter, setCounter] = useState(0);

  useEffect(() => 
    onChange(counter);
  , [counter, onChange]);

  const onClick = () => setCounter(c => c + 1);

  return (
    <div>
      <div>counter</div>
      <button onClick=onClick>Increase</button>
    </div>
  );
;

// ItemDashboard
const Parent = () => 
  const [value, setState] = useState(null);

  useEffect(() => 
    console.log(value);
  , [value]);

  return <Child onChange=setState />;
;

Edit stoic-snow-snu7o

另一答案

我猜,您正在寻找通向共同父母的lift state up的方式。

为了做到这一点,您可以将子组件的事件处理程序(作为道具传递)绑定到其公共父项中的所需回调。

以下现场演示演示了该概念:

const  render  = ReactDOM,
       useState  = React
      
const hobbies = ['cycling', 'DIY', 'hiking'] 

const ChildList = (list) => (
  <ul>
    list.map((li,key) => <li ...key>li</li>)
  </ul>
)
      
const ChildFilter = (onFilter, visibleLabels) => (
  <div>
  
    hobbies.map((hobby,key) => (
      <label ...key>hobby
        <input 
          type="checkbox" 
          value=hobby
          checked=visibleLabels.includes(hobby)
          onChange=e => onFilter(e.target.value, e.target.checked)
        />
      </label>))
  
  </div>
)
      
const Parent = () => 
  const [visibleHobbies, setVisibleHobbies] = useState(['cycling', 'DIY', 'hiking']),
        onChangeVisibility = (hobby,visible) => 
          !visible ?
          setVisibleHobbies(visibleHobbies.filter(h => h != hobby)) :
          setVisibleHobbies([...visibleHobbies, hobby])       
        
   return (
      <div>
        <ChildList list=visibleHobbies />
        <ChildFilter onFilter=onChangeVisibility visibleLabels=visibleHobbies />
      </div>
   )


render (
  <Parent />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

以上是关于我可以使用react中的useEffect挂钩从子级设置父级的状态的主要内容,如果未能解决你的问题,请参考以下文章

从 React 中的 useEffect 挂钩更改复选框选中状态?

反应:仅将主体类添加到 useEffect 挂钩中的某些组件?

为啥我的组件在使用 React 的 Context API 和 useEffect 挂钩时会渲染两次?

无法使用 MaterialTable 中的 useEffect 挂钩显示数据

React - 访问在 useEffect 挂钩中设置的对象属性

无法对未安装的组件执行 React 状态更新(useEffect 反应挂钩)