【问题标题】:Passing array of React components to useState returns empty array将 React 组件数组传递给 useState 返回空数组
【发布时间】:2020-05-22 22:28:05
【问题描述】:

这里的代码非常简单。我想知道这是否是预期的结果。我正在升级一个npm 模块,它需要我将这些项目传递给useState,这在以前是不需要的。不幸的是,我想useState 无法做到这一点?我对吗?我很想错。


props.items 包含一个基于类的 React 组件数组,useState 返回一个空数组:

const [items, set] = useState(props.items);

输入:

输出:

*注意,图像使用在数组内部传播的道具,因为我没有想法,此外,重做所有的东西。

【问题讨论】:

    标签: javascript reactjs react-native react-hooks


    【解决方案1】:

    这并不是真正建议您最好在useEffect 中执行此操作,因为初始状态中的Propsanti-pattern

    const [items, setItems] = useState([]);
    
    
    useEffect(() => {
        setItems(props.items);
      },[props.items]);
    

    【讨论】:

    • 这只会在挂载时设置一次状态。每当 props.items 在父项中发生更改时,除非 props.items 存在于 useEffect 的依赖数组中,否则它不会被反映。
    • 我知道,但在处理非常 ehhhh 的预发布文档时遇到了困难。让我们忽略不应该这样做的事实,谁能告诉我 WHY 结果是一个空数组吗?这就是我在这里真正关心的全部内容,尽管您的回答已被记录下来,并且对于通过 Google 遇到此问题的任何人都很重要。
    • 是的,你当然可以在codesandbox或codepen中添加一个示例,以便我们提供帮助
    • 如果我可以在 CodeSandbox 中重现它,我肯定会包含它。不幸的是,我在 CodeSandbox 中创建的有限示例按您的预期工作,没有返回空数组。转译很有趣,我猜。 --- set 确实是一个保留字,但我并没有真正按预期使用钩子,事实上,我什至不再使用这段代码了。我只对返回的数组为什么为空感兴趣,无论我称它为set 还是setItems 或其他任何东西都是如此。
    • set 不是保留字 :) @Taki
    【解决方案2】:

    使用 react 元素数组作为 useState 的输入应该没有问题。但是,每当您使用来自父级的道具初始化您的状态时,一旦来自父级的道具更改,您还需要重新更新您的状态。否则它将指向在第一遍中从父级传递下来的旧状态。而做到这一点的方法是用 useEffect 钩子做一个 setItems

    useEffect(() => {
       setItems(props.items)
    }, [props.items])
    
    

    顺便说一句,这只会检查新旧数组之间的引用相等性,如果你想进行深度比较,你可能应该使用类似use-deep-compare-effect

    【讨论】:

    • 这是一个硬反模式。为什么要将 props 复制到 state 而不仅仅是使用 props?这样做不可能有一个单一的理由
    • 这样做有一个很好的理由。尝试遵循较差的预发布文档,并尝试遵守它以获得可行的最低可行实施。一旦你理解了,你就可以撕掉反模式。否则,是的;我真的找不到任何正当理由。
    • 它仍然适用。将它放在具有该依赖关系的 useEffect 中仅意味着它将在道具更改时更新。也许初始值会根据 URL 发生变化,但组件永远不会重新挂载。从服务器获取初始值时,可能无法立即获得初始值。底线 - 从道具设置状态本质上不是反模式。仅当状态不需要随时间变化时。
    • @Max 我不知道作者后来在用props初始化的状态做了什么。我只是指出如何在需要时正确重新初始化该值。正如 Brian Thompson 所指出的,在某些合法的用例中,您有一个初始化其状态的组件。如果您不通过 useEffect 重新初始化它,那么如果它们在父级中更改,您将不会收到这些值。同样,根据用例,您可能不关心从父组件传递下来的后续值。因此,根据您的用例,所有可能性都是有效的:)
    • @max 完全正确。根据您的用例,您可能希望有时会发生这种情况(我不知道这是否是作者的意图:耸耸肩:)
    猜你喜欢
    • 2019-06-25
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 2016-12-24
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    相关资源
    最近更新 更多