【问题标题】:Calling set function of useState causes infinite loop调用useState的set函数导致死循环
【发布时间】:2019-12-12 02:40:21
【问题描述】:
import React from 'react';
import Test from './Test';

function App() {
  return (
    <Test />
  );
}

export default App;

import React, { useState } from "react";

const Test = () => {
  const [stuff, setStuff] = useState({ a: "alpha", b: "alpha" });

  setStuff({                // this causes infinite loop!
    ...stuff,               // removing setStuff() fixes it.
    a: "omega"
  });

  return <p>{JSON.stringify(stuff)}</p>;
};

export default Test;

我在 Test.js 中使用 useState() 并且 setStuff() 导致无限循环。

有人可以解释为什么吗?以及如何解决它(如果我想调用 setStuff 来更新东西)?

这是工作代码框:https://codesandbox.io/s/loving-jennings-pr3nl

【问题讨论】:

  • 当你的组件发生变化时,东西应该会发生变化。

标签: reactjs


【解决方案1】:

这行得通

const doStuff=()=>{
    setStuff({
      ...stuff,
      a: "omega"
    });
  };

  useEffect(doStuff,[]);

预期输出:

{"a":"omega","b":"alpha"}

【讨论】:

    【解决方案2】:

    简单的规则是“不要在render函数中设置状态”,因为setState会触发一个render函数,如果在render函数中,你setState,那么它会一直循环下去。

    您应该将“setState”绑定到一个事件,例如鼠标单击、键盘按下或组件完成加载事件,并在该事件中设置状态......但永远不要在渲染函数中。

    在类组件中

    import React from 'react'
    class Test extends React.Component {
      render() {
        // Don't setState here.
        return (<div>test</div>)
      }
    } 
    

    在功能组件中

    const Test = () => {
      // Don't setState here.
      return (<div>test</div>)
    } 
    

    ** 更新

    setState使用示例

    在类组件中

    import React from 'react'
    class Test extends React.Component {
      state = {
        value: 4
      }
    
      handleClickAdd = (e) => {
        const currentValue = this.state.value; 
        this.setState({ value: currentValue + 1 }); // set currentValue + 1 as a new state value.
      }
    
      render() {
        // Don't setState here.
        return (
          <div>
            test {this.state.value}
            <button onClick={this.handleClickAdd}>Add</button>
          </div>
        )
      }
    } 
    

    在功能组件中

    const Test = () => {
    
      const [value, setValue] = useState(4);
    
      const handleClickAdd = e => {
        setValue(value + 1);
      }
    
      // Don't setState here.
      return (
        <div>
          test {value}
          <button onClick={handleClickAdd}>Add</button>
        </div>
      )
    } 
    

    【讨论】:

    • 你能显示 OP 应该在哪里设置状态吗?否则不清楚他们应该在哪里。也许包括一个handleClick 函数或其他东西。
    • 可以使用useEffect()修复吗?
    • 如果您想在组件加载或接收新道具时立即设置状态,那么是的,useEffect 是正确的事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 2021-03-14
    • 2022-01-09
    相关资源
    最近更新 更多