我正在尝试学习钩子(Hook),而 useState 方法让我感到困惑。我正在以数组的形式为状态分配一个初始值。 useState 中的 set 方法对我来说不起作用,无论有没有扩展语法。

我在另一台 PC 上创建了一个 API,我正在调用该 API 并获取我想要设置为状态的数据。

这是我的代码:

<div id="root"></div> 
 
<script type="text/babel" defer> 
// 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> 
 
<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>

setMovies(result)setMovies(...result) 都不起作用。

我希望将 result 变量推送到 movies 数组中。

请您参考如下方法:

很多like .setState() in class components通过扩展 React.ComponentReact.PureComponent 创建,使用 useState 钩子(Hook)提供的更新器进行状态更新也是异步的,并且不会立即反射(reflect)。

此外,这里的主要问题不仅仅是异步性质,而是函数根据其当前闭包使用状态值的事实,并且状态更新将反射(reflect)在现有闭包的下一次重新渲染中不受影响,但会创建新的。现在在当前状态下,hooks 内的值是通过现有闭包获取的,当重新渲染发生时,闭包会根据函数是否再次重新创建而更新。

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

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

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

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

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

但是,如果要将响应与之前存在的值合并,则必须使用状态更新的回调语法以及正确使用扩展语法,例如

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


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!