reactjs - React Redux not updating state despite login working fine
问题描述
So my reducers are not updating the state for my app. The initial state in user shows up with no changes made. The initial state from uiReducer doesn't come up at all. emphasized textI can log in okay and receive a token, so I think it is a problem with getUserData. I have no idea why the ui initial state isn't working however. This is my first time trying to use react redux so I probably have a dumb mistake somewhere. Any help appreciated!
EDIT: Without changing code, I just restarted my app and now both of the initial states are loading, but user is still not populated with data.
login
import React, { Component } from 'react';
import PropTypes from 'prop-types'
// redux
import {connect} from 'react-redux'
import {loginUser} from '../redux/actions/userActions'
class login extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
errors: [],
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.UI.errors) {
this.setState({
errors: nextProps.UI.errors
});
}
}
handleChange = (event) => {
this.setState({
[event.target.name]: event.target.value
});
};
handleSubmit = (event) => {
event.preventDefault();
const userData = {
email: this.state.email,
password: this.state.password
};
this.props.loginUser(userData, this.props.history)
};
render() {
const { classes, UI: {loading} } = this.props;
const { errors } = this.state;
return (
..............
);
}
}
login.propTypes = {
classes: PropTypes.object.isRequired,
loginUser: PropTypes.func.isRequired,
user: PropTypes.object.isRequired,
UI:PropTypes.object.isRequired
}
const mapStateToProps = (state) => ({
user: state.user,
UI: state.UI
})
const mapActionsToProps = {
loginUser
}
export default connect(mapStateToProps, mapActionsToProps)(withStyles(styles)(login));
userActions
import axios from 'axios';
export const loginUser = (userData, history) => (dispatch) => {
dispatch({ type: 'LOADING_UI' });
axios
.post('/login', userData)
.then((res) => {
setAuthorizationHeader(res.data.token);
dispatch(getUserData())
dispatch({type: 'CLEAR_ERRORS'})
history.push('/');
})
.catch((error) => {
dispatch({
type: 'SET_ERRORS',
payload: error.response.data
});
});
}
export const getUserData = ()=> (dispatch) => {
axios
.get('/user')
.then(res => {
dispatch({
type: 'SET_USER',
payload: res.data
})
})
}
const setAuthorizationHeader = (token) => {
const FBIdToken = `Bearer ${token}`;
localStorage.setItem('FBIdToken', FBIdToken);
axios.defaults.headers.common['Authorization'] = FBIdToken;
};
userReducer
const initialState = {
authenticated: false,
credentials: {},
approves: []
}
export default function(state = initialState, action){
switch(action.type){
case 'SET_AUTHENTICATED':
return{
...state,
authenticated: true
}
case 'SET_UNAUTHENTICATED':
return initialState
case 'SET_USER':
return{
authenticated: true,
loading: false,
...action.payload
}
default:
return state
}
}
uiReducer
const initialState = {
loading: false,
errors: null
}
export default function(state = initialState, action) {
switch (action.type) {
case 'SET_ERRORS':
return {
...state,
loading: false,
errors: action.payload
};
case 'CLEAR_ERRORS':
return {
...state,
loading: false,
errors: null
};
case 'LOADING_UI':
return {
...state,
loading: true
};
default:
return state
}
}
I'm really confused that I can log in fine, but the state isnt updated, and only the user state is initialized..
EDIT: store.js
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import userReducer from './reducers/userReducer';
import dataReducer from './reducers/dataReducer';
import uiReducer from './reducers/uiReducer';
const initialState = {};
const middleware = [thunk];
const reducers = combineReducers({
user: userReducer,
data: dataReducer,
UI: uiReducer
});
const store = createStore(reducers,
initialState,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
解决方案
Changing ...action.payload
to user: action.payload
seems to have fixed it. I got the code for this section from a tutorial but the syntax must have been slightly outdated or something, who knows
export default function(state = initialState, action){
switch(action.type){
case 'SET_AUTHENTICATED':
return{
...state,
authenticated: true
}
case 'SET_UNAUTHENTICATED':
return initialState
case 'SET_USER':
return{
authenticated: true,
loading: false,
user: action.payload
}
default:
return state
}
}
推荐阅读
- c# - Delphi WSDL 返回零
- reactjs - 如何删除与 AppSync/Amplify 中的另一个项目相关的项目?
- python - Python - xarray mean between two netcdf files
- r - Modify all the strings between two sets of rows
- javascript - 向电子中的网页发出多行 javascript 调试器请求
- python - 删除 Json 文件 Python 中的对象
- c# - 使用 ReadOnlySpan 对二维数组进行不安全切片
- javascript - 如何根据可用的数据在 React 中为不同的场景设置 State?
- java - 在 Java 程序中关闭注销
- python - Pytube 播放列表不下载任何视频