Javascript 为什么React.memo不能与useffect一起工作?
我是个新手,所以我想要的是,我有一个切换按钮来切换人员组件,还有一个驾驶舱组件。但每当我切换persons组件时,我不想总是重新渲染驾驶舱组件 这是我的caffick.js组件文件Javascript 为什么React.memo不能与useffect一起工作?,javascript,reactjs,Javascript,Reactjs,我是个新手,所以我想要的是,我有一个切换按钮来切换人员组件,还有一个驾驶舱组件。但每当我切换persons组件时,我不想总是重新渲染驾驶舱组件 这是我的caffick.js组件文件 import React, { useEffect } from 'react'; import classes from './Cockpit.css'; const cockpit = props => { useEffect(() => { console.log('[Cockpit
import React, { useEffect } from 'react';
import classes from './Cockpit.css';
const cockpit = props => {
useEffect(() => {
console.log('[Cockpit.js] useEffect');
// Http request...
setTimeout(() => {
alert('Saved data to cloud!');
}, 1000);
return () => {
console.log('[Cockpit.js] cleanup work in useEffect');
};
}, []);
useEffect(() => {
console.log('[Cockpit.js] 2nd useEffect');
return () => {
console.log('[Cockpit.js] cleanup work in 2nd useEffect');
};
});
// useEffect();
const assignedClasses = [];
let btnClass = '';
if (props.showPersons) {
btnClass = classes.Red;
}
if (props.personsLength <= 2) {
assignedClasses.push(classes.red); // classes = ['red']
}
if (props.personsLength <= 1) {
assignedClasses.push(classes.bold); // classes = ['red', 'bold']
}
return (
<div className={classes.Cockpit}>
<h1>{props.title}</h1>
<p className={assignedClasses.join(' ')}>This is really working!</p>
<button className={btnClass} onClick={props.clicked}>
Toggle Persons
</button>
</div>
);
};
export default React.memo(cockpit);
import React,{useffect}来自“React”;
从“/campot.css”导入类;
康斯特驾驶舱=道具=>{
useffect(()=>{
log('[caffict.js]useffect');
//Http请求。。。
设置超时(()=>{
警报(“已将数据保存到云!”);
}, 1000);
return()=>{
log(“[caffict.js]清理工作正在使用中”);
};
}, []);
useffect(()=>{
console.log(“[camport.js]2nd useffect”);
return()=>{
log(“[caffict.js]第二次使用效果中的清理工作”);
};
});
//useffect();
const assignedClasses=[];
让btnClass='';
if(道具表演人员){
btnClass=classes.Red;
}
如果(道具长度){
this.setState({个人:[{姓名:新姓名,年龄:50},{姓名:“艾莎”,年龄:56},{姓名:“妈妈”,年龄:62}]})
}
nameSwitchHandler=(事件,id)=>{
const personIndex=this.state.persons.findIndex(p=>{
返回p.id==id;
})
const person={…this.state.persons[personIndex]}
person.name=event.target.value;
const persons=[…this.state.persons]
人员[人员索引]=人员;
this.setState({persons:persons})
}
togglePersonHandler=()=>{
让doesChange=this.state.showPersons;
this.setState({showPersons:!doesChange})
}
render(){
log(“[App.js]render”);
让person=null;
如果(本.州.表演人){
人=(
);
}
返回(
this.setState({showcocket:false}}>删除驾驶舱
{this.state.showcocket?():null}
{个人}
);
}
}
导出默认应用程序;
但即使我切换它,驾驶舱组件中的useEffect仍然会在浏览器控制台中记录它不应该记录的内容。我似乎找不到我做错了什么
如图所示,驾驶舱中的useEffect组件仍在控制台中呈现……单击Toggle Persons,您正在更改应用程序组件中的状态。 这将导致重新呈现应用程序和驾驶舱组件
useEffect(() => {
console.log('[Cockpit.js] 2nd useEffect');
return () => {
console.log('[Cockpit.js] cleanup work in 2nd useEffect');
};
});
上面的代码将触发每个渲染,因为您没有提供依赖关系。
要解决这个问题,您需要向上述代码添加一个依赖项。因为
showPersons
change它会将其检测为已更改的道具
您可以在<代码> Real.MeMo < /C>中添加一个相等的函数,它在考虑记忆化陈旧时反应:
//仅当某些值发生更改时才会重新加载
导出默认的React.memo(驾驶舱,(oldProps,newProps)=>oldProps.someValue==newProps.someValue)
反应。默认情况下,memo
将对道具
对象进行浅相等比较。这意味着它将检查道具中的每个顶级项目是否相等,如果其中任何一项发生更改,它将重新渲染
当您单击persons toggle按钮时,它将更改应用程序中的showPersons
组件,该组件也是您传递给
的道具。因此,即使使用React.memo
,它也将重新渲染。如果不重新渲染,它将无法正确更新按钮类添加或删除类。红色
>因为这取决于showPersons
prop
它与您的useffect
驾驶舱内部没有任何关系,只有在重新渲染后才会调用useffect
,但不会导致它首先重新渲染。非常感谢,这现在更有意义了。我对真正的反应缺乏了解。备忘录工作原理,这帮助我理解了我真正的错误是什么。
useEffect(() => {
console.log('[Cockpit.js] 2nd useEffect');
return () => {
console.log('[Cockpit.js] cleanup work in 2nd useEffect');
};
});