javascript - React:如何在 App.js 中重新渲染状态变化的路由
问题描述
我有一个 React 应用程序,它呈现两条路由:一个 CreatorView 和一个在 App.js 下路由的 ViewerView(两者都由较小的组件组成)。我遇到的问题是,当我在浏览器的两个不同选项卡中打开两条路由并单击 CreatorView 中组件内的按钮时,我使用回调来更改/设置 App.js 的状态(首先我从组件到 CreatorView,然后从 CreatorView 我将状态传递给 App.js 并设置 App.js 的状态)。最后,我将 App.js 的新状态传递给 ViewerView,这是一个路由组件,因为我希望它重新渲染以显示其他内容。理论上,当我单击 CreatorView 中的按钮时,App.js 会重新渲染(由于状态更改)以及路由(CreatorView 和 ViewerView)。但是,只有 CreatorView 似乎会随着这种状态变化而重新渲染。ViewerView 没有 即使通过 App.js 更改其状态,它似乎也在更新/重新渲染。换句话说,一旦我单击另一个选项卡中的 CreatorView 中的按钮,如何使 ViewerView 重新渲染,它已经在另一个选项卡中打开。我在下面提供了我的文件层次结构和我的代码:
┣ elements
┃ ┗ CreatorControlPanel.js #contains the button which will trigger set state in App.js
┃ ┗ CreatorHeader.js
┃ ┗ ViewerControlPanel.js
┃ ┗ ViewerHeader.js
┣ views
┃ ┗ CreatorView.js #contains CreatorControlPanel & CreatorHeader
┃ ┗ ViewerView.js #contains ViewerControlPanel & ViewerHeader
应用程序.js
class App extends Component {
constructor() {
super()
this.state = {
click: false
}
this.setClicked = this.setClicked.bind(this)
}
setClicked() {
this.setState({click: true})
}
render() {
return (
<Router>
<Switch>
<Route path="/:snippetId/creator" exact render={() => ( <CreatorView clickedCallback={this.setClicked}/> )} />
<Route path="/:snippetId" render={() => ( <ViewerView clicked={this.state.click}/> )} />
</Switch>
</Router>
);
}
}
CreatorControlPanel.js
import { MyContext } from '../views/MyProvider';
class CreatorControlPanel extends Component {
constructor(props) {
state = {...}
handleClick() {
this.props.clickCallback();
}
render() {
return(
<Button onClick={this.handleClick}>Click me</Button>{' '}
)
}
}
CreatorView.js
import CreatorControlPanel from '../elements/CreatorControlPanel';
class CreatorView extends Component {
state = { ... }
setClicked() {
this.props.clickedCallback();
}
render() {
return(
<CreatorControlPanel clickCallback={this.setClicked}/>/>
)
}
}
ViewerView.js
class ViewerView extends Component {
state = {
click: null
}
componentDidMount() {
this.setState({click: this.props.clicked})
}
render() {
if(this.state.click === false){
return (
<div>hi, hello</div>
)
} else return (
<div>clicked</div> #ViewerView won't re-render to display this once clicked
)
}
解决方案
您可以使用use-persisted-state将视图持久化到 localStorage
import createPersistedState from 'use-persisted-state';
const useView = createPersistedState('click');
const CreatorView = () => {
const [click, setClick] = useView(false);
return (<div>{click}</div>)
};
const ViewerView = () => {
const [click, setClick] = useView(false);
return (<div>{click}</div>)
}
您的所有窗口和选项卡使用相同的键共享该状态。因此,如果您在窗口选项卡 1 的 CreatorView 中将单击设置为 true,它也会反映在窗口选项卡 2 的 ViewerView 中。
由于它使用localStorage,您可以存储一些事件,但我不建议您保存大数据。它不是为此而设计的。
推荐阅读
- ios - 如何从不同的模块更改 Rootview 控制器?
- ansible - 即使字符串不匹配,也可以显示该值
- python - Python 脚本中的 BS4 错误.. 在 PyCharm 中运行良好,但在 OS 中运行良好
- c - 有人可以将二进制代码解释为无符号整数吗
- c++ - 来自多个线程的 std::cout
- dashdb - 云上的 DB2。将配置 STRING_UNITS 更改为 CODEUNITS32
- python - 如何覆盖调用脚本中的变量?
- html - 如何更改引导程序 4 轮播中的导航按钮?
- c# - 在绑定列上设置元素集合的 DataGridViewComboBoxColumn 不允许用户下拉
- vuejs2 - 如何在 vue2-daterange-picker 中实现“清除”按钮?