如何在点击 React-Router-Dom NavLink 时强制重新渲染 React-Redux 组件?
How to force a re-render of React-Redux components upon React-Router-Dom NavLink click?
我有一个使用 React-Router-Dom 构建的 React 应用程序用于导航。这些页面大量使用 table 可以以 CRUD 形式打开的数据。由于我们在 table 中的记录数量,用户对 table 应用排序、过滤和分页以查找所需记录的情况并不少见。
作为一个相当标准的网络应用程序,我们在页面的左侧有一个导航栏。这是由 NavLinks 组成的。
应用程序的主体是一个组件 MainPanel
,它几乎完全只是 Switch
:
中的一系列 Route
组件
<Switch>
<Route path="/page1" component={ComponentOne} />
<Route path="/page2" component={ComponentTwo} />
</Switch>
我现在收到上面的请求,当用户选择其中一个 NavLink 时,它应该作为页面主体中所有内容的 "reset"。特别是,对于 table(排序、筛选、页面等)的所有设置,这应该充当 "reset"。
这 似乎 几乎应该是微不足道的,因为我所要做的就是触发重新呈现包含 table 的页面主面板.但是,我在 React-Router-Dom 的文档中找不到任何包含此关键的内容。
有人知道我错过了什么吗?没有 easy/right 方式说“单击此 link 时,总是重新渲染 MainPanel 吗?
您可以在状态中保留一个值,例如名为 panelKey
,用作主面板的 key
道具。然后当 link 被点击时,你给 panelKey
一个新值,React 将丢弃主面板并创建一个全新的组件。
例子
class Timer extends React.Component {
timer = null;
state = { count: 0 };
componentDidMount() {
this.timer = setInterval(() => {
this.setState(prevState => ({ count: prevState.count + 1 }));
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return <div>{this.state.count}</div>;
}
}
class MainPanel extends React.Component {
state = { panelKey: 1 };
onClick = () => {
this.setState(prevState => ({ panelKey: prevState.panelKey + 1 }));
};
render() {
return (
<div key={this.state.panelKey}>
<button onClick={this.onClick}> Reset Panel </button>
<Timer />
</div>
);
}
}
ReactDOM.render(<MainPanel />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我看到你在标签中列出了 react-redux,为什么不发送一个自定义操作来通知其他组件应该重置过滤器?
import { LOCATION_CHANGE } from 'react-router-redux';
import { resetFilter } from './filterActions.js';
const resetFilterMiddleware = ({ dispatch }) => next => action => {
// Listen for a location chnage
if(action.type === LOCATION_CHANGE){
dispatch(resetFilter()); // { type: 'RESET_FILTER' } or something along the lines
}
next(action);
}
export default resetFilterMiddleware;
我有一个使用 React-Router-Dom 构建的 React 应用程序用于导航。这些页面大量使用 table 可以以 CRUD 形式打开的数据。由于我们在 table 中的记录数量,用户对 table 应用排序、过滤和分页以查找所需记录的情况并不少见。
作为一个相当标准的网络应用程序,我们在页面的左侧有一个导航栏。这是由 NavLinks 组成的。
应用程序的主体是一个组件 MainPanel
,它几乎完全只是 Switch
:
Route
组件
<Switch>
<Route path="/page1" component={ComponentOne} />
<Route path="/page2" component={ComponentTwo} />
</Switch>
我现在收到上面的请求,当用户选择其中一个 NavLink 时,它应该作为页面主体中所有内容的 "reset"。特别是,对于 table(排序、筛选、页面等)的所有设置,这应该充当 "reset"。
这 似乎 几乎应该是微不足道的,因为我所要做的就是触发重新呈现包含 table 的页面主面板.但是,我在 React-Router-Dom 的文档中找不到任何包含此关键的内容。
有人知道我错过了什么吗?没有 easy/right 方式说“单击此 link 时,总是重新渲染 MainPanel 吗?
您可以在状态中保留一个值,例如名为 panelKey
,用作主面板的 key
道具。然后当 link 被点击时,你给 panelKey
一个新值,React 将丢弃主面板并创建一个全新的组件。
例子
class Timer extends React.Component {
timer = null;
state = { count: 0 };
componentDidMount() {
this.timer = setInterval(() => {
this.setState(prevState => ({ count: prevState.count + 1 }));
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return <div>{this.state.count}</div>;
}
}
class MainPanel extends React.Component {
state = { panelKey: 1 };
onClick = () => {
this.setState(prevState => ({ panelKey: prevState.panelKey + 1 }));
};
render() {
return (
<div key={this.state.panelKey}>
<button onClick={this.onClick}> Reset Panel </button>
<Timer />
</div>
);
}
}
ReactDOM.render(<MainPanel />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我看到你在标签中列出了 react-redux,为什么不发送一个自定义操作来通知其他组件应该重置过滤器?
import { LOCATION_CHANGE } from 'react-router-redux';
import { resetFilter } from './filterActions.js';
const resetFilterMiddleware = ({ dispatch }) => next => action => {
// Listen for a location chnage
if(action.type === LOCATION_CHANGE){
dispatch(resetFilter()); // { type: 'RESET_FILTER' } or something along the lines
}
next(action);
}
export default resetFilterMiddleware;