问题描述
今天重构项目的路由代码,遇到了一个问题,在app.js 的文件中,我使用react-router路由如下:
<Route exact path='/program/:programId/task/:taskId/section/:sectionId/excellent-assignment-list' component={ExcellentAssignmentListPageBody}/>
在组件ExcellentAssignmentListPageBody中我点击某链接的时候跳转到另一个页面ExcellentAssignmentPageBody,代码如下:
goExcellentSection (sectionId) {
this.props.history.push('/student/program/1/task/1/section/1/excellent-assignment')
}
现象:在前端页面中我点击按钮本来应该跳转的ExcellentAssignmentListPageBody页面中,但是并没有,直接跳到了ExcellentAssignmentPageBody页面
矛盾点
根据路由分析,应该跳转页面到ExcellentAssignmentListPageBody,而不是直接跳转到ExcellentAssignmentPageBody,只有点击ExcellentAssignmentListPageBody页面内的链接,才会跳转ExcellentAssignmentPageBody,这是为什么呢?
问题解决
Q1:开始怀疑是在app.js 中写错了路由的组件名?
A1:仔细检查后发现,路由和组件都是对的。
Q2:接着怀疑是react-router 的问题,是用错了?
A2: 网上搜索后发现使用方法是的对的
Q3: 在ExcellentAssignmentListPageBody页面,console.log()打印了一个字符串,结果在控制台中打印出来了,说明该组件确实被渲染,渲染后瞬间就跳往了另一个组件,仔细看在控制台有这样的错误:proxyConsole.js:54 Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
从提示上来看,是因为我在render 里面或者是constructor 里面使用了setState吗?
A3: 在项目中全局搜索setState,并没有在render 或contructor 里面setState.那么问题在哪?展开错误提示,发现了这样的一句代码<a onClick={this.goExcellentSection(this, excellentHomework.section.id)}>作业链接</a>
,有一种想拔根头发分分钟吊死的冲动。。。
Q4:分析一下,为什会这样?
A4:网上搜索,bind()方法会创建一个新函数,当这个新函数被调用时,它的this值是传递给bind()的第一个参数, 它的参数是bind()的其他参数和其原本的参数. 什意思呢?bind即将goExcellentSection函数与这个组件Component进行绑定以确保在这个处理函数中使用this时可以时刻指向这一组件。
如果没有bind的话,像之前那样,那么就成函数调用了。当代码执行到这里的时候们就直接调用了,调用后push 了路由,页面的渲染自然也就变了。。。
加上bind后,问题就解决了
反思
- 开发中没有做到小步提交,一下子改了很多代码,不能快速的诊断问题在哪里
- 不仔细看错误的提示,没有点开错误,导致浪费了很多的时间
action
- 开发时,小步提交
- 遇到问题时从提示中找解决方法,仔细看提示