记录有关react-router的坑

更新


[2019-7-21]

  • Initial release

[2019-7-22]

Added

  • 新增问题react-router-dom-v4嵌套组件, href改变, 但是子组件不渲染

记录


解决: 利用shouldComponentUpdate判断前后的pathname是否相同, 来进行优化.

展开代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
public static getDerivedStateFromProps(
nextProps: IAdminProps,
) {
return {
pathname: nextProps.location.pathname,
};
}

public readonly state = {
pathname: '',
};

public shouldComponentUpdate(
nextProps: IAdminProps,
): boolean {
const currentPathname: string = this.state.pathname;
const nextPathname: string = nextProps.location.pathname;

return nextPathname !== currentPathname;
}
...

2. Failed prop type: Invalid prop component of type object supplied to Route, expected function

解决:

展开代码
1
2
3
4
5
<Route
component={
() => <App />
}
/>

也可以:

展开代码
1
2
3
4
5
<Route
render={
() => <App />
}
/>

3. react-router-dom-v4嵌套组件, href改变, 但是子组件不渲染

相关依赖:

产生原因:

困扰了我8个月的问题😂😂😂…

今日无意中在react-router-dom官网找到原因, 粘贴一下原文:

https://reacttraining.com/react-router/core/guides/redux-integration

展开代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Generally, React Router and Redux work just fine together. Occasionally though, an app can have a component that doesn’t update when the location changes (child routes or active nav links don’t update).

一般情况下, `react-router``redux`是绝妙的搭配. 但是有时会出现突发情况, 当`location`发生改变时, `react`应用可能不会发生更新(特别是`子路由``activeLink`锚点).

This happens if:

1. The component is connected to redux via connect()(Comp).
2. The component is not a “route component”, meaning it is not rendered like so: <Route component={SomeConnectedThing}/>

1. 组件通过`connect()(Comp)`连接`redux`
2. 当通过`<Route component={SomeConnectedThing} />`定义路由, 此时`SomeConnectedThing`并不是一个`route`组件.

The problem is that Redux implements shouldComponentUpdate and there’s no indication that anything has changed if it isn’t receiving props from the router. This is straightforward to fix. Find where you connect your component and wrap it in `withRouter`.

产生这种问题的根本原因是`redux`内部实现了`shouldComponentUpdate`, 如果它的`props`没有变化, 那么就不会产生更新, 从而子组件不会重新渲染. **解决办法是使用`withRouter`包裹该组件**.

解决办法:

  • 如果在component中传递的不是当前组件的子组件, 需要在其每个孩子组件加上withRouter, 因为当前组件发生更改了, 其子组件的props并没有发生变化, 后续同理.

  • 还有另一种办法, 就是不要用React.memo, 或者PureComponent.