更新 React useState 中的对象数组

时间:2021-04-08 06:47:48

标签: javascript arrays reactjs react-hooks

我有一个 ListItem 类,它是一个 Item 列表。它有一些函数,例如更新列表中的项目的 setItem 和添加项目的 addItem 和设置 filterItem

visible

Item 是一个看起来像 {name,number,discount,visible}

的对象

我有一个像这样的伪代码的视图 ListItemView

export default function ListItemView() {

    const [items, setItems] = useState([])

    useEffect(() => {
        setItems(new ListItem(getItems()))
    }, [])
    
    function toggleChange(f,newF){
        setItems((current) => current.setItem(f,newF))
    }

    function filter(search){
        setItems(Items.filterItem({search}))
    }

    return (
        <>
            <button onClick={() => setItems(items.addItem())}> ADD Item</button>
            <input onChange={(e) => filter(e.target.value)} />
            {items.items.map((Item) =>
               !item.visible && item.visible !== undefined  ? null :
               <div key={Item.id}>
                  <ItemLine f={item} toggleChange={toggleChange} />
               </div>
            )}
        </>
    )
}

ItemLine 只是一个组件,用于显示带有我的项目数据的输入

我的问题是:

  • 要更新我的项目,我是否必须每次都使用 setItems?因为它导致页面的完整重新呈现,这对我来说很愚蠢,因为当我们只是在整个列表的一个对象中设置 1 个数据时?

  • 当我打字时我的过滤器功能很快(过滤我的列表),但是当我必须重新显示列表中的每个项目时它很慢,300个项目将无法使用,我该怎么办改变这个?

  • 我听说过 ReactHook 表单,它对我有用吗?

感谢您的专业知识:)

1 个答案:

答案 0 :(得分:2)

<块引用>

要更新我的项目,我是否必须每次都使用 setItems?因为 它导致页面的完整重新渲染,这对我来说很愚蠢 因为当我们只是在整个对象的一个​​对象中设置 1 个数据时 列表?

是的,即使是添加一个元素或更新一个元素,您也需要调用 setItems 来更新您的状态。

但是,您可以通过将映射值转换为组件并使用 React.memo 避免重新渲染来优化重新渲染。

function Item = React.memo(({item, toggleChange}) => {
   return !item.visible && item.visible !== undefined  ? null :
        <div key={Item.id}>
                  <ItemLine f={item} toggleChange={toggleChange} />
         </div>
})
export default function ListItemView() {

    const [items, setItems] = useState([])

    useEffect(() => {
        setItems(new ListItem(getItems()))
    }, [])

    // using useCallback to have only one instaance of toggleChange being created even on re-renders 
    const toggleChange = useCallback(function toggleChange(f,newF){
        setItems((current) => current.setItem(f,newF))
    }, []);

    function filter(search){
        setItems(Items.filterItem({search}))
    }

    return (
        <>
            <button onClick={() => setItems(items.addItem())}> ADD Item</button>
            <input onChange={(e) => filter(e.target.value)} />
            {items.items.map((Item) =>
               <Item key={item.id} item={item} toggleChange={toggleChange}/>
            )}
        </>
    )
}
<块引用>

当我打字时,我的过滤器功能很快(在我的列表中过滤), 但是当我必须重新显示列表中的每个项目时,速度非常慢, 有 300 件物品将无法使用,我该如何更改?

如果您要渲染大型列表,则应针对这些列表进行虚拟化,即仅渲染视图中的项目。 react-windowreact-virtualized 是您可以探索的热门库。