useState 挂钩未使用正确值初始化:数组

Posted

技术标签:

【中文标题】useState 挂钩未使用正确值初始化:数组【英文标题】:useState hook not initialising with correct value: Array 【发布时间】:2020-06-01 09:21:51 【问题描述】:

我将一个数组“默认值”传递给我的面板组件,然后尝试将状态挂钩“选定选项”设置为等于它。由于某种原因,钩子设置了一个空数组。

组件:

const Panel = ( title, inputs, datepicker, identifiers, apiBase, isins, defaults = [], notes = "" ) => 
    const [expand, setExpand] = useState(false);
    const [date, setDate] = useState(new Date());
    const [selectedOption, setSelectedOption] = useState([...defaults]);
    const [dataError, setDataError] = useState(false);
    const [errorMsg, setErrorMsg] = useState('');
    const [errorCheckLoading, setErrorCheckLoading] = useState(false);

    const toggleExpand = () => 
        setExpand(!expand);
        console.log(defaults);
        console.log(selectedOption);
    ;

仅用于测试,我的切换扩展功能中有几个控制台日志,因此我可以针对数据集测试传入的数据。

控制台日志的输出:

>(48) […, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, 
 …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, …, 
 …, …, …, …, …, …, …, …]
>[]

所以我知道数据正常,只是它没有设置在挂钩中。

我也尝试过为钩子提供默认值和 [defaults] 的初始值。

现在画一个空白 - 有什么想法吗?

编辑:这是提供默认值的父组件:

const Parent = () => 

    const [all, setAll] = useState([]);
    const [allLoadFailed, setAllLoadFailed] = useState(false);

    const [defaults, setDefaults] = useState([]);
    const [defaultsLoadFailed, setDefaultsLoadFailed] = useState(false);

    useEffect(() =>  loadData(), []);
    useEffect(() =>  loadDefaultData(), []);

    const loadDefaultData = async () => 
        try 
            let defaultData = await GetDefaults();
            setDefaults(defaultData.map(item => item = value: item, label: item));
         catch (_) 
            setDefaultsLoadFailed(true);
        
    ;

    const loadData = async () => 
        try 
            let iData = await GetAll();
            let filteredIData = iData.filter(item => item);
            setAll(filteredIData.map(item => item = value: item, label: item));
         catch (_) 
            setAllLoadFailed(true);
        
    ;


    return (

            <Panel
                title="Test"
                isins=all
                defaults=defaults
                inputs
                datepicker
                identifiers
                apiBase=""
                notes="not yet complete"
                key="2"
            />
    );

【问题讨论】:

【参考方案1】:

我在这里猜测defaults 是来自 api 调用的值?

出现这种情况是因为在初始渲染defaults = []useState的第一个参数只获取初始值,所以当default在第二个渲染中更改为正确的数据时,useState已经有了@ 987654326@值。

你应该做的是在defaults更改和设置selectedOption时使用useEffect钩子。

useEffect(() => 
    setSelectedOption([...defaults])       
, [defaults, setSelectedOption])

【讨论】:

哦,太好了,效果很好。我没有意识到你可以看到 useEffect 依赖项中的任何值——在我看来,它只是状态挂钩。很好,谢谢。 嗯,我刚刚注意到这个解决方案正在触发“超出最大更新深度”警告。可能会触发父组件的重新渲染,在哪里进行 api 调用? @这是因为if 真的吗?即使我从@Claeusdev 将解决方案恢复到以下内容,仍然会发生 @PeteG 你能分享一下defaults 的来源吗?【参考方案2】:

检查您的解构,您将默认值设置为defaults = []。它只会先渲染空数组,然后组件将完成它的挂载。您可能想使用useEffect 挂钩来检查新更新,然后在其中设置setSelectedOption(defaults),如下所示:

useEffect(() => 
   setSelectedOption(defaults)
, [defaults])

【讨论】:

以上是关于useState 挂钩未使用正确值初始化:数组的主要内容,如果未能解决你的问题,请参考以下文章

使用 JSON 数据输出数组数组而不是一个数组来反应 useState Hooks

用于显示初始数据的效果挂钩

useState 在 useEffect 中定义后保持初始状态

useState 数组在创建重复项时未正确更新

C++,布尔数组未正确初始化

我们如何在 useState 中使用 redux state 来设置初始值