Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/363.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 为什么传递给memo的道具是don';不要存储值_Javascript_Reactjs_React Hooks_Use State_React Memo - Fatal编程技术网

Javascript 为什么传递给memo的道具是don';不要存储值

Javascript 为什么传递给memo的道具是don';不要存储值,javascript,reactjs,react-hooks,use-state,react-memo,Javascript,Reactjs,React Hooks,Use State,React Memo,我正在尝试使用手动道具比较的React memo功能优化我的React列表呈现。我已经生成了一个简单的“切换”按钮列表: import React,{useState}来自“React”; 导入“/styles.css”; 从“/Toggle”导入{Toggle}; 导出默认函数App(){ const[list,setList]=useState({a:true,b:true,c:true}); 常量handleClick=x=>{ 控制台日志(列表); 常数currentValue=列表[x

我正在尝试使用手动道具比较的React memo功能优化我的React列表呈现。我已经生成了一个简单的“切换”按钮列表:

import React,{useState}来自“React”;
导入“/styles.css”;
从“/Toggle”导入{Toggle};
导出默认函数App(){
const[list,setList]=useState({a:true,b:true,c:true});
常量handleClick=x=>{
控制台日志(列表);
常数currentValue=列表[x];
setList({…list,[x]:!currentValue});
};
返回(
你好,代码沙盒
{Object.keys(list.map)(x=>(
))}
);
}
这是“切换”按钮:

从“React”导入React;
常量areEqual=(prevProps,nextProps)=>{
返回prevProps.isChecked==nextrops.isChecked;
};
const-ToggleComponent=({isChecked,name,onChange})=>{
返回(
{isChecked?“这是真的”:“这是假的”}
onChange(name)}>{name}
);
};
export const Toggle=React.memo(ToggleComponent,areEqual);
我的问题是列表对象实际上没有存储预期的值。每次单击按钮,我都会得到相同的默认按钮
{a:true,b:true,c:true}
(它在
控制台.log
handleClick
中可见),但是如果我删除
areEqual
函数,一切都会正常工作,列表对象会按原样更新

编辑:

我看到,如果我把整个东西变成一个数组,并把每个按钮都包装成一个对象,备忘录功能就会按预期工作


这是因为创建了
handleClick
函数并将其传递给
切换组件一次。
而
handleClick的
闭包包含旧的
列表
值,因此每当旧值更改时,它不会得到更新

最简单的修复方法是利用状态更新程序的第二个签名:一个在参数中接受旧状态值的函数

因此,无论何时调用它,react都会将旧的状态值传递给它

const handleClick = x => {
  setList(old => ({ ...old, [x]: !old[x] }));
};
您还需要
memoize
handleClick函数,因为它是在保存状态的组件的每次渲染时重新创建的:

const handleClick = React.useCallback(x => {
  setList(old => ({ ...old, [x]: !old[x] }));
}, [setList]);
这里有工作

const handleClick = x => {
  setList(old => ({ ...old, [x]: !old[x] }));
};
const handleClick = React.useCallback(x => {
  setList(old => ({ ...old, [x]: !old[x] }));
}, [setList]);