Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 更新处于React useState状态的对象数组_Javascript_Arrays_Reactjs_React Hooks - Fatal编程技术网

Javascript 更新处于React useState状态的对象数组

Javascript 更新处于React useState状态的对象数组,javascript,arrays,reactjs,react-hooks,Javascript,Arrays,Reactjs,React Hooks,我有一个类ListItem,它是项的列表。它有一些函数,比如更新列表中的项目的setItem,添加项目的addItem,以及设置可见的的filterietem Item是一个看起来像{name,number,折扣,visible} 我有一个视图ListItemView,带有这样一个伪代码 export default function ListItemView() { const [items, setItems] = useState([]) useEffect(() =&

我有一个类
ListItem
,它是
项的列表。它有一些函数,比如更新列表中的项目的
setItem
,添加项目的
addItem
,以及设置可见的
filterietem

Item
是一个看起来像
{name,number,折扣,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>
            )}
        </>
    )
}
导出默认函数ListItemView(){
const[items,setItems]=useState([])
useffect(()=>{
setItems(新列表项(getItems()))
}, [])
功能切换更改(f、newF){
setItems((当前)=>current.setItem(f,newF))
}
函数过滤器(搜索){
setItems(Items.filterItem({search}))
}
返回(
setItems(items.addItem())}>添加项
过滤器(如target.value)}/>
{items.items.map((Item)=>
!item.visible&&item.visible!==未定义?空:
)}
)
}
ItemLine
只是一个用我的项目数据显示输入的组件

我的问题是:

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

  • 我的过滤功能在我打字时很快(在我的列表中过滤),但当我必须重新显示列表中的每个项目时,它相当慢,因为有300个项目它将无法使用,我如何更改它

  • 我听说过ReactHook表单,它在这里对我有用吗

感谢您的专业知识:)


要更新我的项目,是否每次都必须使用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}/>
            )}
        </>
    )
}
function Item=React.memo({Item,toggleChange})=>{
return!item.visible&&item.visible!==未定义?空:
})
导出默认函数ListItemView(){
const[items,setItems]=useState([])
useffect(()=>{
setItems(新列表项(getItems()))
}, [])
//使用useCallback仅创建一次toggleChange,即使在重新渲染时也是如此
const toggleChange=useCallback(函数toggleChange(f,newF){
setItems((当前)=>current.setItem(f,newF))
}, []);
函数过滤器(搜索){
setItems(Items.filterItem({search}))
}
返回(
setItems(items.addItem())}>添加项
过滤器(如target.value)}/>
{items.items.map((Item)=>
)}
)
}
我的过滤功能在我打字时很快(在我的列表上过滤), 但当我必须重新显示列表中的每一项时,速度相当慢, 300件物品将无法使用,如何更改


如果要呈现大型列表,则应将其虚拟化,即仅呈现视图中的项目。这些都是很受欢迎的库,您可以为此进行探索。

“我每次都被迫使用setItems吗”是的,React就是这样工作的。React是非常现成的优化工具,可以轻松处理渲染几百个元素的数组。您的
items
状态是一个数组,状态更新程序对您的状态做了什么,即
current.setItem(f,newF)
?您正在映射
项。项
,因此现在我认为您的
状态实际上不是一个数组,并且您的装载
useffect
正在改变状态形状。我已经更改了
初始状态,它应该是
新列表项()
但是我的装载
useffect
项目设置为
新列表项目(someitems)
其中
someitems
是我从数据库中获取的项目数组
current.setItem(f,newF)
将在
items.items中搜索
f
旧的
item
,并放置
newF
作为新项,例如新名称。也许我应该显示
ListItem
类,但它只是一个带有
的类。items
作为状态如果我们考虑在React中编写代码的性能,我不知道React中什么是对的,什么是错的,只是盲目地相信它可能是好的@Nur重要的是自己尝试代码实现,并不断在devtools中分析以了解影响。React还支持最新版本的探查器,以帮助您完成此操作。