在react js中的useEffect之后未设置State



我的react应用程序中有下一个组件:

import React, { useEffect, useState } from "react";
import AsyncSelect from "react-select/async";
import { ColourOption, colourOptions } from "./docs/data";
const App = () => {
const [state, setState] = useState([]);
useEffect(() => {
setState(colourOptions);
}, []);
return (
<AsyncSelect
cacheOptions
defaultOptions
loadOptions={async () => new Promise((r) => r(state))}
/>
);
};
export default App;

我在useEffect中设置了colourOptions,然后在loadOptions中读取了state。现在,当我打开选择时,这些选项不会出现,但当我将loadOptions={async () => new Promise((r) => r(state))}更改为loadOptions={async () => new Promise((r) => r(colourOptions))}时,会出现下拉项
如何使我的代码在state的第一种情况下可用,使用useEffect
演示:https://codesandbox.io/s/codesandboxer-example-forked-b3857?file=/example.tsx:355-409

问题是,状态是在useEffect调用之后设置的(要测试这一点,只需在JSX中映射状态并记录每个数组索引(。react-select的异步组件中的loadOptions函数似乎只使用其道具作为依赖项进行了内存化,因此您不会因为在useEffect中设置了状态就获得新的loadOptions函数。换句话说,在组件的新渲染中,即使状态已更新,选项也将保持不变。问题是,为什么要使用useEffect

在我看来,您在示例中调用useEffect来模拟异步调用,就像您想要获取一些数据时所做的那样。通常,当人们想要获取数据时,他们会将异步调用放入useEffect,并在第一次渲染后获取数据。问题是,react-select的异步组件公开的loadOptions函数已经提供了这个功能——也就是说,它会在你需要的时候异步地为你获取选项,而不是等待一个额外的步骤来进行状态更新,这可能会迫使您以编程方式重新实例化loadOptions函数(通过更改像defaultOptions这样的道具或其他可能更黑客的东西(。

TLDR只使用loadOptions函数作为异步数据提取器,而不是等待useEffect

首先,状态是异步的,这意味着在设置状态后不能立即获得其值。

所以这个问题可以通过初始化状态来解决。

const [state, setState] = useState(colourOptions);

由于状态设置是异步的,您可以尝试在选项状态保持未定义的情况下添加加载屏幕,类似

return (
{state?
<AsyncSelect
cacheOptions
defaultOptions
loadOptions={async () => new Promise((r) => r(state))}
/>
:
<SomeLoadingScreen/>
}
);

最新更新