React Redux 组件不更新
React Redux components does not update
我正在尝试使用 React + Redux(SSR 和 Thunks)实现身份验证(符号 up/out)。我不知道为什么当 Redux 状态更新时组件没有更新...
这是应该重新呈现的组件:
class Navbar extends React.Component {
constructor(props) {
super(props);
this.state = {
loggedIn: props.authentication.loggedIn
};
}
render() {
let links = null;
if (this.state.loggedIn) {
links = ...
} else {
links = ...
}
return (<Toolbar>{links}</Toolbar>)
}
}
const mapStateToProps = state => {
return {
authentication: state.authentication
}
}
const mapDispatchToProps = dispatch => {
return {
signOut: () => {dispatch(userActions.logout())}
}
}
const AuthNavbar = connect(mapStateToProps, mapDispatchToProps)(Navbar)
export default AuthNavbar;
那是我的减速器:
const reducers = {
authentication,
registration,
alert
}
const todoApp = combineReducers(reducers)
export default todoApp
认证减速器:
const authentication = (state = initialState, action) => {
switch (action.type) {
...
case userConstants.LOGIN_SUCCESS:
return Object.assign({}, state, {
loggedIn: true,
loggingIn: false,
user: action.user
});
...
default:
return state;
}
}
以及操作 - 登录:
function login(email, password) {
return dispatch => {
dispatch({type: userConstants.LOGIN_REQUEST, email});
userService.login(email, password).then(
user => {
dispatch({type: userConstants.LOGIN_SUCCESS, user});
},
error => {
dispatch({ type: userConstants.LOGIN_FAILURE });
dispatch({type: alertActions.error(error)});
}
);
}
}
UserService.login是一个调用apifetch的函数。
看起来 Action 被触发了,Redux 状态被更新了,但是组件没有更新:
仔细检查 Redux 开发工具 - 状态确实得到更新,所以我使用连接实用程序的方式一定有问题吗?
您正在 constructor
内的状态中存储 logedin
道具,这将 运行 在组件的生命周期中仅一次。
当一个新的道具回来时,你并没有更新状态。
要么直接使用道具:
if (this.props.authentication.loggedIn) {
links = ...
中的状态
componentWillReceiveProps(nextProps){
// update the state with the new props
this.setState({
loggedIn: nextProps.authentication.loggedIn
});
}
您的 render
功能依赖于 state.loggedIn
,但 state.loggedIn
没有改变;只有 this.props.authentication.loggedIn
正在响应该操作而发生变化。当前形式的组件不需要状态。您可以删除它以使其正常工作:
class Navbar extends React.Component {
render() {
let links = null;
if (this.props.authentication.loggedIn) {
links = ...
} else {
links = ...
}
return (<Toolbar>{links}</Toolbar>)
}
}
我正在尝试使用 React + Redux(SSR 和 Thunks)实现身份验证(符号 up/out)。我不知道为什么当 Redux 状态更新时组件没有更新...
这是应该重新呈现的组件:
class Navbar extends React.Component {
constructor(props) {
super(props);
this.state = {
loggedIn: props.authentication.loggedIn
};
}
render() {
let links = null;
if (this.state.loggedIn) {
links = ...
} else {
links = ...
}
return (<Toolbar>{links}</Toolbar>)
}
}
const mapStateToProps = state => {
return {
authentication: state.authentication
}
}
const mapDispatchToProps = dispatch => {
return {
signOut: () => {dispatch(userActions.logout())}
}
}
const AuthNavbar = connect(mapStateToProps, mapDispatchToProps)(Navbar)
export default AuthNavbar;
那是我的减速器:
const reducers = {
authentication,
registration,
alert
}
const todoApp = combineReducers(reducers)
export default todoApp
认证减速器:
const authentication = (state = initialState, action) => {
switch (action.type) {
...
case userConstants.LOGIN_SUCCESS:
return Object.assign({}, state, {
loggedIn: true,
loggingIn: false,
user: action.user
});
...
default:
return state;
}
}
以及操作 - 登录:
function login(email, password) {
return dispatch => {
dispatch({type: userConstants.LOGIN_REQUEST, email});
userService.login(email, password).then(
user => {
dispatch({type: userConstants.LOGIN_SUCCESS, user});
},
error => {
dispatch({ type: userConstants.LOGIN_FAILURE });
dispatch({type: alertActions.error(error)});
}
);
}
}
UserService.login是一个调用apifetch的函数。
看起来 Action 被触发了,Redux 状态被更新了,但是组件没有更新:
您正在 constructor
内的状态中存储 logedin
道具,这将 运行 在组件的生命周期中仅一次。
当一个新的道具回来时,你并没有更新状态。
要么直接使用道具:
if (this.props.authentication.loggedIn) {
links = ...
中的状态
componentWillReceiveProps(nextProps){
// update the state with the new props
this.setState({
loggedIn: nextProps.authentication.loggedIn
});
}
您的 render
功能依赖于 state.loggedIn
,但 state.loggedIn
没有改变;只有 this.props.authentication.loggedIn
正在响应该操作而发生变化。当前形式的组件不需要状态。您可以删除它以使其正常工作:
class Navbar extends React.Component {
render() {
let links = null;
if (this.props.authentication.loggedIn) {
links = ...
} else {
links = ...
}
return (<Toolbar>{links}</Toolbar>)
}
}