useState设置方法不能立即反映更改 [英] useState set method not reflecting change immediately

查看:59
本文介绍了useState设置方法不能立即反映更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习钩子,而useState方法使我感到困惑.我正在将初始值分配给数组形式的状态.即使使用spread(...)without spread operatoruseState中的set方法对我也不起作用. 我已经在另一台PC上创建了一个API,该API正在调用并获取要设置为状态的数据.

I am trying to learn hooks and the useState method has made me confused. I am assigning an initial value to a state in the form of an array. The set method in useState is not working for me even with spread(...) or without spread operator. I have made an API on another PC that I am calling and fetching the data which I want to set into the state.

这是我的代码:

<script src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="root"></div>

<script type="text/babel">
// import React, { useState, useEffect } from "react";
// import ReactDOM from "react-dom";
const { useState, useEffect } = React; // web-browser variant

const StateSelector = () => {
  const initialValue = [
    {
      category: "",
      photo: "",
      description: "",
      id: 0,
      name: "",
      rating: 0
    }
  ];

  const [movies, setMovies] = useState(initialValue);

  useEffect(() => {
    (async function() {
      try {
        // const response = await fetch("http://192.168.1.164:5000/movies/display");
        // const json = await response.json();
        // const result = json.data.result;
        const result = [
          {
            category: "cat1",
            description: "desc1",
            id: "1546514491119",
            name: "randomname2",
            photo: null,
            rating: "3"
          },
          {
            category: "cat2",
            description: "desc1",
            id: "1546837819818",
            name: "randomname1",
            rating: "5"
          }
        ];
        console.log("result =", result);
        setMovies(result);
        console.log("movies =", movies);
      } catch (e) {
        console.error(e);
      }
    })();
  }, []);

  return <p>hello</p>;
};

const rootElement = document.getElementById("root");
ReactDOM.render(<StateSelector />, rootElement);
</script>

setMovies(result)setMovies(...result)无法正常工作.可以在这里使用一些帮助.

The setMovies(result) as well as setMovies(...result) is not working. Could use some help here.

我希望将结果变量推入movies数组中.

I expect the result variable to be pushed into the movies array.

推荐答案

与通过扩展React.ComponentReact.PureComponent创建的Class组件中的setState相似,使用由useState钩子提供的更新程序的状态更新也是异步的,并且不会立即反映出来.

Much like setState in Class components created by extending React.Component or React.PureComponent, the state update using the updater provided by useState hook is also asynchronous, and will not be reflected immediately.

此外,这里的主要问题不仅在于异步性质,还在于函数根据其当前闭包使用状态值的事实,并且状态更新将反映在现有闭包的下一次重新呈现中不会受到影响,但会创建新的.现在,在当前状态下,挂钩中的值是由现有的闭包获得的,并且当重新渲染时,将根据是否再次创建该函数来更新闭包.

Also, the main issue here is not just the asynchronous nature but the fact that state values are used by functions based on their current closures, and state updates will reflect in the next re-render by which the existing closures are not affected, but new ones are created. Now in the current state, the values within hooks are obtained by existing closures, and when a re-render happens, the closures are updated based on whether the function is recreated again or not.

即使添加了setTimeout函数,尽管超时将在发生重新渲染的一段时间后运行,但setTimeout仍将使用其先前关闭的值而不是更新的值

Even if you add a setTimeout the function, though the timeout will run after some time by which the re-render would have happened, the setTimeout will still use the value from its previous closure and not the updated one.

setMovies(result);
console.log(movies) // movies here will not be updated

如果要对状态更新执行操作,则需要使用useEffect钩子,就像在类组件中使用componentDidUpdate一样,因为useState返回的setter没有回调模式

If you want to perform an action on state update, you need to use the useEffect hook, much like using componentDidUpdate in class components since the setter returned by useState doesn't have a callback pattern

useEffect(() => {
    // action on update of movies
}, [movies]);

就更新状态的语法而言,setMovies(result)会将状态中的先前movies值替换为异步请求中可用的值.

As far as the syntax to update state is concerned, setMovies(result) will replace the previous movies value in the state with those available from the async request.

但是,如果您想将响应与先前存在的值合并,则必须使用状态更新的回调语法以及正确使用诸如

However, if you want to merge the response with the previously existing values, you must use the callback syntax of state updation along with the correct use of spread syntax like

setMovies(prevMovies => ([...prevMovies, ...result]));

这篇关于useState设置方法不能立即反映更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆