首页 文章

何时使用React setState回调

提问于
浏览
95

当react组件状态发生变化时,将调用render方法 . 因此,对于任何状态更改,可以在呈现方法主体中执行操作 . 那么setState回调是否有特定的用例?

4 回答

  • 11

    是的,因为 setStateasynchronous 方式工作 . 这意味着在调用 setStatethis.state 变量不会立即更改 . 因此,如果要在状态变量上设置状态后立即执行操作然后返回结果,则回调将非常有用

    考虑下面的例子

    ....
    changeTitle: function changeTitle (event) {
      this.setState({ title: event.target.value });
      this.validateTitle();
    },
    validateTitle: function validateTitle () {
      if (this.state.title.length === 0) {
        this.setState({ titleError: "Title can't be blank" });
      }
    },
    ....
    

    由于 title 变量在对其执行验证之前可能未发生变异,因此上述代码可能无法正常工作 . 现在您可能想知道我们可以在 render() 函数本身中执行验证,但如果我们可以在changeTitle函数本身处理它,那将会更好更清洁,因为这会使您的代码更有条理和易懂

    在这种情况下,回调很有用

    ....
    changeTitle: function changeTitle (event) {
      this.setState({ title: event.target.value }, function() {
        this.validateTitle();
      });
    
    },
    validateTitle: function validateTitle () {
      if (this.state.title.length === 0) {
        this.setState({ titleError: "Title can't be blank" });
      }
    },
    ....
    

    另一个例子是当你希望 dispatch 和状态改变时的动作 . 你会想要在回调而不是 render() 中进行,因为每次重新渲染都会调用它,因此很多这样的场景都可能需要回调 .

    One Another case is a API Call

    当您需要根据特定的状态更改进行API调用时,可能会出现这种情况,如果您在render方法中执行此操作,则会在每次render onState 更改时调用它,或者因为某些Prop传递给 Child Component 已更改 .

    在这种情况下,您可能希望使用 setState callback 将更新的状态值传递给API调用

    ....
    changeTitle: function (event) {
      this.setState({ title: event.target.value }, () => this.APICallFunction());
    },
    APICallFunction: function () {
      // Call API with the updated value
    }
    ....
    
  • 34

    我想到的1. usecase是一个 api 调用,它不应该进入渲染,因为它将运行 each 状态更改 . API调用应仅在特殊状态更改时执行,而不是在 every render上执行 .

    changeSearchParams = (params) => {
      this.setState({ params }, this.performSearch)
    } 
    
    performSearch = () => {
      API.search(this.state.params, (result) => {
        this.setState({ result })
      });
    }
    

    因此,对于任何状态更改,可以在呈现方法主体中执行操作 .

    Very bad practice ,因为 render -method应该是纯粹的,这意味着不应该执行任何动作,状态更改,api调用,只需合成视图并将其返回 . 应仅对某些事件执行操作 . 渲染不是一个事件,而是 componentDidMount .

  • 127
    this.setState({
        name:'value' 
    },() => {
        console.log(this.state.name);
    });
    
  • 9

    setState是一个异步函数

    所以你不能非常依赖它 . 例如,让我们考虑在时间t = 0 . 应用程序中的不同点在您的应用程序中调用了两个setState函数 . Before t=0 they were referring same sate . 同时触发它们将仅修改此状态 . 假设其中一个在t = 3处完成执行,从而修改了状态并创建了一个新状态(调用它 state_1 ) . 现在第二个setState在t = 4处完成 . 它在 initial State 中修改并创建了新状态(将其称为 state_2 ) . 这个新状态( state_2 )与 state_1 不同 . 因此我们可能存在数据差异 .

    因此 whenever your new state is dependent on previous State use state call back method . prevState总是指在内存中最后修改的结果的状态 . 因此,利用prevState的回调函数永远不会导致数据的差异 .

    错误的代码:

    this.setState(
       {counter:this.state.counter+1}
     );
    

    Correct Code with setState having call back function:

    this.setState(
           (prevState,props)=>{
               return {counter:prevState.counter+1};
            }
        );
    

    通常,回调用于在发生某些事情时运行某些代码 . 因此,当setState调用成功时更新状态 .

相关问题