我正在使用Flux,它的运行效果很好,但是我现在正尝试以一种方式使用它,即助焊剂存储确定所有子组件的单个真相或状态点。
我基本上是在尝试实现auth系统,该系统确定当前用户的auth状态,而不必通过执行以下操作来单独更新每个组件的状态(其中有很多):
state = {
authenticated: AuthStateStore.getState(),
uid: AuthStateStore.getUid(),
token: AuthStateStore.getToken(),
username: AuthStateStore.getUsername(),
avatar: AuthStateStore.getAvatar(),
errors: []
}
我以为我可以在主要的父<App/>
组件上设置状态(其他所有内容都作为孩子呈现),然后将状态作为道具传递给所有孩子。这确实有效-{this.props.state.authenticated}
将在子级中显示<App/>
的正确状态-但是道具是不可变的,这意味着当<App />
的状态通过通量存储更新时,没有一个用<App/>
中的新值更新发送给孩子的道具。
有什么方法可以实现我在这里想要做的事情,还是必须以这种方式从每个需要信息的组件的焊剂存储中设置状态?
编辑:我是如何从<App/>
传递状态的(我已经减少了脂肪,使它们更易读)。
应用(主要父级)
class App extends Component {
state = {
authenticated: AuthStateStore.getState(),
uid: AuthStateStore.getUid(),
token: AuthStateStore.getToken(),
username: AuthStateStore.getUsername(),
avatar: AuthStateStore.getAvatar()
}
render() {
return (
<BrowserRouter>
<div>
<Sidebar state={this.state}/>
<Switch>
<Route exact path="/" component={Home} state={this.state}/>
<Route exact path="/signup" component={Signup} state={this.state}/>
<Route path="/activate/([\da-f]+)" component={Activate}/>
.......
</Switch>
<Footer />
</div>
</BrowserRouter>
);
}
}
侧边栏(第一个孩子)
class Sidebar extends Component {
render() {
return (
<div className="sidebar">
<Navigation state={this.props.state}/>
<Search/>
</div>
);
}
}
导航(第二个孩子)
class Navigation extends Component {
render() {
if (this.props.state.authenticated === "true") {
return (
<div>
<p>Authenticated content here</p>
</div>
);
} else {
return (
<div>
<p>Non-authenticated content here</p>
</div>
);
}
}
}
上面的代码在第一次加载时有效,但是如果<App/>
的状态通过助焊剂存储发生变化,除非您进行了整页的重新加载(我们显然不希望这样做),否则这不会反映在子级中要做)。
进一步编辑...
简而言之,现在我可以通过在每个需要Auth状态信息的子组件中执行以下操作来工作(再次为便于阅读而对脂肪进行了修剪)...
class Navigation extends Component {
state = {
authenticated: AuthStateStore.getState(),
uid: AuthStateStore.getUid(),
token: AuthStateStore.getToken(),
username: AuthStateStore.getUsername(),
avatar: AuthStateStore.getAvatar()
}
componentWillMount() {
AuthStateStore.on("change", () => {
this.setState({
authenticated: AuthStateStore.getState(),
uid: AuthStateStore.getUid(),
token: AuthStateStore.getToken(),
username: AuthStateStore.getUsername(),
avatar: AuthStateStore.getAvatar()
});
});
}
render() {
if (this.state.authenticated === "true") {
return (
<div>
<p>Authenticated content here</p>
</div>
);
} else {
return (
<div>
<p>Non-authenticated content here</p>
</div>
);
}
}
}
...但是本着DNRY的精神,并试图避免由于忘记在某个地方的组件中调用或设置状态而导致的任何潜在陷阱,我正在寻找另一种“一站式服务”,我希望助焊剂能够提供的解决方案。