【发布时间】:2016-06-24 15:18:11
【问题描述】:
我有四个 React 组件:
- 整体父母(
App或类似) -
Header孩子,由App调用 -
Profile页面 -
LogoutLink,由Profile调用
我正在使用Auth0 实现用户身份验证/登录系统。当用户登录时(通过Header 中的登录按钮),App 更改User 对象的Context 以包含从Auth0 检索到的所有数据。然后,系统的任何需要它的部分都可以访问此用户数据。
登录后,UI 会自动更新(使用 Context 更改),因此 Header 现在显示“嘿,{name}”而不是之前的“登录”。这也是一个指向 Profile 页面/组件的链接(使用 React Router 的 <Link to="/profile></Link> 元素)。
在Profile 页面上有一个LogoutLink。单击时,这会将用户注销,然后返回主页。它还应该自动更新 UI 以将 Header 中的消息从“Hey there {name}”改回“Login”。这是通过Context 再次更改来完成的。然而,这个功能实际上并没有起作用——用户成功退出,但要看到上面描述的变化,用户需要刷新整个页面。 this.context.user 没有更新并发送回Profile 和Header。 我知道这是因为 Redux,它是单向数据流(即数据只能向下,不能向上),但我需要找到解决方法。
这是我的基本代码:
LogoutLink.js
export default class LogoutLink extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
this.state = {
user: null,
};
}
static propTypes = {
value: React.PropTypes.string,
}
static contextTypes = {
user: React.PropTypes.object,
} // get context so this.context is available to get initial user data (before logout)
static childContextTypes = {
user: React.PropTypes.object,
}
getChildContext() {
return {user: this.state.user}
} // these two are for updating context
componentWillMount() {
this.setState({ user: this.context.user });
} // set the internal LogoutLink state
onClick() {
this.setState({ user: null }); // set the internal user state to null following logout
}
renderLogoutLink() {
const {value} = this.props;
const {user} = this.state;
if (user != null) {
return <Link to="/profile" onClick={this.onClick}>{value}</Link>
} else {
return <span>You're already logged out!</span>
}
}
render() {
return <span>{this.renderLogoutLink()}</span>
}
}
Header.js:
export default class Header extends React.Component { // eslint-disable-line react/prefer-stateless-function
constructor(props) {
super(props);
this.showLock = this.showLock.bind(this); // lock is the Auth0 module responsible for Login, also passed down by context
}
static contextTypes = {
user: React.PropTypes.object,
lock: React.PropTypes.object,
}
showLock() {
const {lock} = this.context;
lock.show();
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
if (this.context.user == null && nextContext.user != null) {
return true;
} else if (this.context.user != null && nextContext.user == null) {
return true;
}
return false;
} // after the LogoutLink is clicked, this still returns false
renderLoginButton() {
const {user} = this.context;
if (user) {
const name = user.nickname;
return <Link to="/profile">Hey there {name}!</Link>
} else {
return <button onClick={this.showLock}>Login</button>
}
}
render() {
return (
<header>
{this.renderLoginButton()}
</header>
);
}
}
我正在关注有关 Context 的官方 React 文档并对其进行更新,可在此处找到:https://facebook.github.io/react/docs/context.html
正如我所说,我知道为什么这不起作用:数据只能以一种方式发送。但我需要找到一种方法来完成这项工作,老实说,我认为我已经盯着这个太久了,现在没有选择,我的大脑有点疲惫。
【问题讨论】:
-
header shouldComponentUpdate 中 nextContext 的值是什么,应该是更新的 shouldComponentUpdate 可能是这里的罪魁祸首。请检查 nextContext.user
-
嗨 Piyush -
nextContext.user等于this.context.userintHeader组件shouldComponentUpdate- 当LogoutLink更改上下文时它不会改变。
标签: javascript reactjs redux