简体   繁体   English

如何更新 state 但不触发无限 useEffect 循环?

[英]How do I update state but not trigger the infinite useEffect loop?

I'm trying to update state in a higher-order component from a child.我正在尝试从孩子的高阶组件中更新 state。 My solution is to set state to true after setting tags.我的解决方案是在设置标签后将 state 设置为 true。 useEffect runs when state is true, firstly updating state in the parent component and then updating state to false, which halts its invocation. useEffect 在 state 为 true 时运行,首先更新父组件中的 state,然后将 state 更新为 false,从而停止其调用。 My aforementioned solution is the only way I've managed to prevent useEffect's infinite loop.我前面提到的解决方案是我设法防止 useEffect 无限循环的唯一方法。

  const Student = ({ 
  appendTags,
  student: {
    id: studentId,
    firstName,
    lastName,
    pic,
    email,
    company,
    skill, 
    grades,
    tags: studentTags
  }}) => {
  const fullName = `${firstName} ${lastName}`;
  const [tag, setTag] = useState('');
  const [tags, setTags] = useState([]);
  const [stateUpdated, setStateUpdated] = useState(false);
  const [displayGrades, setDisplayGrades] = useState(false);
  
  const onTagsSubmit = e => {
    if (tag.length) {
      e.preventDefault();
      
      setTags(prevState => [...prevState, tag]);
      setStateUpdated(true);
      setTag('');
    }
  }
  useEffect(() => {
    if (stateUpdated) {
      appendTags(studentId, tags);
      setStateUpdated(false);
    };
  }, [stateUpdated, setStateUpdated, tags, appendTags, studentId]);

Looks like this is what we have, if you remove stateUpdated .如果您删除stateUpdated ,看起来这就是我们所拥有的。

I presume than on appendTags() call the parent component changes its state and gets re-rendered.我认为在appendTags()调用父组件时会更改其 state 并重新渲染。 After that the appendTags function is recreated.之后,重新创建appendTags function。 The child component Student is recreated, too.子组件Student也被重新创建。 Student's useEffect sees that one of the dependencies, appendTags , has changed, so it has to be re-executed.学生的useEffect发现其中一个依赖appendTags已更改,因此必须重新执行它。 It calls the appendTags() and we have a loop.它调用appendTags()并且我们有一个循环。

To fix it, you need to wrap appendTags into useCallback hook inside the parent component:要修复它,您需要将appendTags包装到组件内的useCallback钩子中:

const appendTags = useCallback((id, tags) => {
  // update local state
}, []);
// ...
return <Student appendTags={appendTags} /* (...) */ />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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