将 useState 与 promise 一起使用是否只是一次设置值的好习惯?

Is using useState with promise just to set value once a good practice?

我想知道在 React 中使用 useState 仅设置一次值是否被认为是一种好的做法,如果不是,如何改进它。

假设我有一个简单的组件,它只是获取一些数据并将它们显示在下拉列表中:

import React, {useState, useEffect} from 'react';
import {utilities} from './utils';

const Component = (props) => {
    const [ingredients, setIngredients] = useState([]);

    useEffect(() => {
        new Promise((resolve, reject) => {
            const res = utilities.getIngredients();
            if (res.data) {
                resolve("Stuff worked!");
            }
            else {
                reject(Error("It broke"));
            }
        }).then((response) => {
            setIngredients(response);
        });

    }, []);

    return (
        <div>
            <p>Choose from possible ingredients:</p>
            <Select options={ingredients}/>
        </div>
    );
}

export default Component;

既然setIngredients只调用了一次,那么在这里使用useState是不是太过分了?我的直觉告诉我,可能有更好的方法来做到这一点。另一方面,当我尝试只使用一个变量时,我们没有更新值并且下拉列表没有显示任何选项(这是有道理的,因为数据是在呈现下拉列表之后到达的)。 能否请您判断这里有哪些地方可以改进?

State 在需要持久性 跨渲染 时使用。如果您的组件被重新渲染(反应决定何时发生),未解决的承诺(如 Axios 使用的承诺或在您的问题示例中使用的承诺)仍然会解决并可以为变量赋值 - 但这些变量实际上并没有不再存在。当一个函数组件被重新渲染时,任何声明的变量都会被初始化,就好像这是函数组件的第一个运行(它实际上只是一个函数)。 Promise 持有的任何对“普通”变量的引用(以传统方式 letconstvar 声明,而不是通过 React Hooks 声明)将不再与 Promise 使用的变量相同下一个 运行.

上的函数组件

举个例子来说明:

const Component = (props) => {
    let nonStateIngredients = []; //will get initialised to [] every render

    useEffect(() => {
        doSomethingThatTakesAWhile()
          .then((response) => {
            // If the Component has been re-rendered
            // by the time we get here, the next line will not
            // do anything
            nonStateIngredients = response.ingredients;
            // If not, the above line will work,
            // but as soon as we rerender, it will be reinitialised 
            // to []
          });
    }, []);

任何不属于 React Hook 的部分都将被重新初始化。

因此,在 React 中,我们使用:

  • 用于存储数据的“普通”(letconst)变量派生自渲染中的现有状态或道具,或者在组件的生命周期内保持不变
  • 用于存储必须跨渲染持续存在的数据的状态(可以随时间变化的数据)
  • Memos(或 Memoized 变量)存储始终派生的数据,但派生成本高(需要大量处理能力)(这是“普通”变量的优化)

为了更直接地回答您的问题,当我们使用 State 检索和分配值时,这不是最佳实践 - 这是唯一可行的方法。