Javascript 反应-作为道具使用,产生额外的渲染效果
我正在处理一些重的表格。因此,我在尽可能地压缩性能。最近,我添加了Why Doy you render插件,以便更深入地了解哪些因素可能会降低我的页面速度。例如,我注意到,当我单击复选框组件时,所有其他组件都会重新渲染。理由总是一样的。WDYR说 由于道具更改而重新渲染:使用 同名{prev onChangeHandler:ƒ}”!==“{下一个onChangeHandler:ƒ}” 我尽可能地尊重我发现的最佳实践指示。我的组件传递的回调函数遵循以下模式Javascript 反应-作为道具使用,产生额外的渲染效果,javascript,reactjs,Javascript,Reactjs,我正在处理一些重的表格。因此,我在尽可能地压缩性能。最近,我添加了Why Doy you render插件,以便更深入地了解哪些因素可能会降低我的页面速度。例如,我注意到,当我单击复选框组件时,所有其他组件都会重新渲染。理由总是一样的。WDYR说 由于道具更改而重新渲染:使用 同名{prev onChangeHandler:ƒ}”!==“{下一个onChangeHandler:ƒ}” 我尽可能地尊重我发现的最佳实践指示。我的组件传递的回调函数遵循以下模式 import React, { useS
import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
export function TopLevelComponent({props}){
const defaultData = {name: '', useMale: false, useFemale: false}
const [data, setData] = useState(defData);
const { t } = useTranslation();
const updateState = (_attr, _val) => {
const update = {};
update[_attr] = _val;
setData({ ...data, ...update });
}
const updateName = (_v) => updateState('name', _v);//Text input
const updateUseMale = (_v) => updateState('useMale', _v);//checkbox
const updateUseFemale = (_v) => updateState('useFemale', _v);//checkbox
...
return <div>
...
<SomeInputComponent value={data.name} text={t('fullName')} onChangeHandler={updateName} />
<SomeCheckboxComponent value={data.useMale} onChangeHandler={updateUseMale} text={t('useMale')}/>
<SomeCheckboxComponent value={data.useFemale} onChangeHandler={updateUseFemale} text={t('useFemale')}/>
...
</div>
}
import React,{useState,useffect}来自“React”;
从“react-i18next”导入{useTranslation};
导出函数TopLevelComponent({props}){
const defaultData={name:'',UseMeal:false,UseMeal:false}
const[data,setData]=使用状态(defData);
const{t}=useTranslation();
const updateState=(\u attr,\u val)=>{
常量更新={};
更新[\u attr]=\u val;
setData({…数据,…更新});
}
const updateName=(_v)=>updateState('name',_v);//文本输入
const updateUseMale=(\u v)=>updateState('useMean',\u v);//复选框
const updateUseFemale=(\u v)=>updateEstate('useFemale',\u v);//复选框
...
返回
...
...
}
在这样的示例中,更改任何输入(例如:在文本输入中写入文本或单击其中一个复选框)都会导致其他2个组件按照上面给出的对齐方式重新渲染
我想我可以停止使用功能组件,使用
shouldComponentUpdate()
函数,但功能组件确实提供了一些我宁愿保留的优势。我应该如何编写函数,使与一个输入交互时不会强制更新另一个输入?问题源于您定义更改处理程序的方式:
const updateName = (_v) => updateState('name', _v)
在每次渲染时都会调用这一行,因此,每次渲染组件时,道具都会有一个新的(尽管功能上完全相同)值。其他处理程序也是如此
作为一个简单的解决方案,您可以将功能组件升级为成熟的组件,并在渲染功能之外缓存处理程序,也可以在子组件中实现。您需要对子组件使用
memo
来减少渲染
const SomeInputComponent=props=>{
};
导出默认备忘录(SomeInputComponent);
//如果它仍然导致重新渲染而不改变任何道具,则可以使用回调来允许或阻止渲染
e、 f。
功能arePropsEqual(前一个Props,下一个Props){
return prevProps.name===nextProps.name;//使用您的逻辑来确定props是否相同
}
导出默认备忘(SomeInputComponent,arePropsEqual);
/*重新渲染的一个原因是,传递给子组件的“onChange”回调在每个父级渲染上都是新的,这会导致子组件重新渲染,即使您使用“momo”,因为函数在每个渲染上都会更新,所以为了修复此问题,您可以使用React hook“useCallback”在每个渲染上获得相同的函数引用。
因此,在父组件中,需要执行以下操作
*/
从“react”导入{useCallback};
const updateName=useCallback((_v)=>UpdateEstate('name',_v),[])
在传递给子函数之前,必须先记住父函数,对函数组件使用useCallback,如果使用class,则转换为class属性
export default class Parent extends React.PureComponent {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick() {
console.log("click");
}
render() {
return (
<ChildComponent
onClick={ this.onClick }
/>
);
}
}
导出默认类父级扩展React.PureComponent{
建造师(道具){
超级(道具);
this.onClick=this.onClick.bind(this);
}
onClick(){
控制台日志(“单击”);
}
render(){
返回(
);
}
}
使用useCallback:
Parent = () => {
const onClick = useCallback(
() => console.log('click'),
[]
);
return (
<ChildComponent
onClick={onClick}
/>
);
}
Parent=()=>{
const onClick=useCallback(
()=>console.log('click'),
[]
);
返回(
);
}
您能再添加一点代码让我们理解吗。我们有memo
和usemo
等工具来减少不必要的成本renders@ZohaibIjaz您想要组件特定的函数吗?实际上,我不知道是哪个组件导致了更改,哪些组件得到了渲染,而这些组件不需要渲染。@ZohaibIjaz添加了更多的代码。我试着使用memo
,但对于需要更复杂数据的组件,我得到了一些奇怪的结果。如果这是解决方案,我将尝试使用memo调试代码。您是否使用上下文作为状态?您的状态驻留在哪里?当传递给子组件的值是对象时,您将如何使用memo?对于某些组件,我有一些复杂的数据对象,我尝试了类似memo(MyComponent,(\u prev,\u next)=>JSON.stringify(\u prev.values)===JSON.stringify(\u next.values))代码>但这似乎不起作用。我需要逐个属性进行比较吗?@Axel查看关于使用useCallback
的更新答案。我希望它能解决您的问题,您不需要在memo()
中传递额外的arePropsSame
回调,我尝试使用useCallback
将我的所有回调看起来像const updateFnc=useCallback((_v)=>updateState('someAttr',u v),[])
但这只更改了WDYR:Re-rendered的错误代码,因为props对象本身已更改,但其值都相等。单击复选框后,文本输入中会出现该错误