Javascript 为什么React.memo不能与useffect一起工作?

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

我是个新手,所以我想要的是,我有一个切换按钮来切换人员组件,还有一个驾驶舱组件。但每当我切换persons组件时,我不想总是重新渲染驾驶舱组件

这是我的caffick.js组件文件

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');
    };
  });