javascript - 将功能作为道具发送给它时反应组件重新渲染
问题描述
我有一个子组件StartExam
,我从父组件发送两个函数作为道具。我看到它一直在重新渲染,因为它一直在获取新的函数值。我已经使用这段代码来找出正在更新的道具,它给了我发送的两个函数。
componentDidUpdate(prevProps, prevState, snapshot) {
Object.entries(this.props).forEach(([key, val]) =>
prevProps[key] !== val && console.log(`Prop '${key}' changed`)
);
if (this.state) {
Object.entries(this.state).forEach(([key, val]) =>
prevState[key] !== val && console.log(`State '${key}' changed`)
);
}
}
这就是我从父组件发送函数的方式:
<Route path={`${matchedPath}/start`}
render={
this.examStatusGuard(
'NOT_STARTED',
(props) =>
<StartExam
language={this.state.language}
startExam={() => this.startExam()}
logAction={(action) => this.logAction({action})}/>)
}
/>
这是examStatusGuard
功能:
examStatusGuard(requiredState, renderFunc) {
return (props) => {
if (this.state.exam.status !== requiredState) {
return <Redirect to={this.examStatusDefaultUrl()}/>
}
return renderFunc(props);
}
}
这是我作为道具发送的两个功能:
logAction(actionModel) {
const wholeActionModel = {
language: this.state.language,
taskId: null,
answerId: null,
...actionModel
};
console.log(wholeActionModel);
return wholeActionModel;
}
startExam() {
this.logAction({action: actions.EXAM_STARTET});
this.examGateway.startExam()
.then(() => this.loadExam())
.then(() => {
this.props.history.push("/exam/task/0");
this.logAction({action: actions.TASK_OPEN, taskId: this.state.exam.tasks[0].id});
});
};
我不希望重新创建函数的原因是在子组件中我有一个调用 的方法logAction
,并且它一直被调用,而不是只调用一次。这是方法:
renderFirstPage() {
this.props.logAction(actions.INFOSIDE_OPEN);
return <FirstPage examInfo={this.props.eksamensInfo}>
{this.gotoNextPageComponent()}
</FirstPage>
}
我尝试发送答案中建议的功能,但绑定this
到它们:
<StartExam
language={this.state.language}
startExam={this.startExam.bind(this)}
logAction={this.logAction.bind(this)}/>
但是,这些功能一直在重新创建。我怎样才能解决这个问题?
解决方案
当您像您一样发送函数时,您正在创建一个匿名函数,每次父组件呈现时都会重新创建该函数:
startExam={() => this.startExam()}
那是一个匿名函数,它的全部目的就是调用实际的函数startExam
。它是在父级的渲染函数中定义的,因此每次都会重新创建它。您也可以只发送该功能本身,即
startExam={this.startExam}
在这种情况下,道具现在引用了一个不会每次都重新创建的稳定函数。我想这会解决你的问题。
但是,我并不完全清楚为什么每次都重新创建函数并且重新渲染您的子组件很重要。道具不会改变无限的时间,而只会在父级重新渲染时改变。这通常不是问题,除非您基于其他一些操作来查看以前的道具是否已更改(例如使用 lodash, _.isEqual(prevProps,this.props)
)。
推荐阅读
- sql - 在 SQL 中只插入唯一记录
- sql - 在 Redshift 中,如何从 stl_insert 获得准确的插入计数?
- node.js - 如何将调整大小的图像从锐利发送回用户?
- nestjs - Nest 无法解析 RabbitMQService 服务的依赖关系
- c - 可以存储在 long double 中的最大整数
- r - 根据满足 R 中 2 as.Date 列中的条件创建列
- flutter - 添加透明容器后无法滚动
- wpf - 如何消除 .NET 5 WPF 程序中的警告 NETSDK1137?
- google-analytics - 如何比较来自搜索和谷歌分析导航的综合浏览量?
- javascript - 使用multer在nodejs中上传图像后,json文件中的图像url出现问题