I am using Redux
as a Flux
alternative and React
for the view layer. My application's React
and Redux
are bound with react-redux
connect()
method.
When running the application it dispatches the action when the ponents mounts and the redux returns the correct state. However the redux-logger
logs in the console that the store has updated with the new state, in the ponent when checking this.props.session
it still shows the old state. I am guessing that I'm not using the connect
method correctly, however I can't define the issue with it as well. Does anyone have an idea whats going on?
containers/App
'use strict';
import React from 'react';
import {connect} from 'react-redux';
import {fetchUserSession} from 'actions/SessionActions';
class App extends React.Component {
constructor(props) {
super(props);
}
ponentWillMount() {
const {dispatch, session} = this.props;
dispatch(fetchUserSession());
console.log(session);
// logs:
// Object {currentUserId: null, errorMessage: null, isSessionValid: null}
// store is bound to window, and the initial state is ImmutabeJS object
console.log(window.store.getState().session.toJS());
// logs:
// Object {currentUserId: null, errorMessage: null, isSessionValid: false}
// as you might noticed the isSessionValid is changed to false
}
render() {
// html here
}
}
function mapStateToProps(state){
return {
session: state.session.toJS()
};
}
export default connect(mapStateToProps)(App);
actions/Actions.js
'use strict';
import fetch from 'isomorphic-fetch';
export const SESSION_REQUEST = 'SESSION_REQUEST';
export const SESSION_SUCCESS = 'SESSION_SUCCESS';
export function requestSession() {
return {
type: SESSION_REQUEST
};
}
export function receiveSession(user) {
return {
type: SESSION_REQUEST,
user
};
}
export function fetchUserSession() {
return dispatch => {
dispatch(requestSession());
return fetch(`http://localhost:5000/session`)
.then((response) => {
if (response.status === 404) {
dispatch(raiseSessionFailure(response));
}
return response.json();
})
.then(userData => dispatch(receiveSession(userData)));
};
}
reducers/SessionReducer.js
'use strict';
import {fromJS} from 'immutable';
// UPDATE!!!
// here is the initial state
const initialState = fromJS({
currentUserId: null,
errorMessage: null,
isSessionValid: null
});
function sessionReducer(state = initialState, action) {
switch (action.type) {
case 'SESSION_REQUEST':
return state.update('isSessionValid', () => false);
case 'SESSION_SUCCESS':
console.log('Reducer: SESSION_SUCCESS');
return state;
case 'SESSION_FAILURE':
console.log('Reducer: SESSION_FAILURE');
return state;
default:
return state;
}
}
export default sessionReducer;
reducers/RootReducer
'use strict';
import {bineReducers} from 'redux';
import sessionReducer from 'reducers/SessionReducer';
const rootReducer = bineReducers({
session: sessionReducer
});
export default rootReducer;
I am using Redux
as a Flux
alternative and React
for the view layer. My application's React
and Redux
are bound with react-redux
connect()
method.
When running the application it dispatches the action when the ponents mounts and the redux returns the correct state. However the redux-logger
logs in the console that the store has updated with the new state, in the ponent when checking this.props.session
it still shows the old state. I am guessing that I'm not using the connect
method correctly, however I can't define the issue with it as well. Does anyone have an idea whats going on?
containers/App
'use strict';
import React from 'react';
import {connect} from 'react-redux';
import {fetchUserSession} from 'actions/SessionActions';
class App extends React.Component {
constructor(props) {
super(props);
}
ponentWillMount() {
const {dispatch, session} = this.props;
dispatch(fetchUserSession());
console.log(session);
// logs:
// Object {currentUserId: null, errorMessage: null, isSessionValid: null}
// store is bound to window, and the initial state is ImmutabeJS object
console.log(window.store.getState().session.toJS());
// logs:
// Object {currentUserId: null, errorMessage: null, isSessionValid: false}
// as you might noticed the isSessionValid is changed to false
}
render() {
// html here
}
}
function mapStateToProps(state){
return {
session: state.session.toJS()
};
}
export default connect(mapStateToProps)(App);
actions/Actions.js
'use strict';
import fetch from 'isomorphic-fetch';
export const SESSION_REQUEST = 'SESSION_REQUEST';
export const SESSION_SUCCESS = 'SESSION_SUCCESS';
export function requestSession() {
return {
type: SESSION_REQUEST
};
}
export function receiveSession(user) {
return {
type: SESSION_REQUEST,
user
};
}
export function fetchUserSession() {
return dispatch => {
dispatch(requestSession());
return fetch(`http://localhost:5000/session`)
.then((response) => {
if (response.status === 404) {
dispatch(raiseSessionFailure(response));
}
return response.json();
})
.then(userData => dispatch(receiveSession(userData)));
};
}
reducers/SessionReducer.js
'use strict';
import {fromJS} from 'immutable';
// UPDATE!!!
// here is the initial state
const initialState = fromJS({
currentUserId: null,
errorMessage: null,
isSessionValid: null
});
function sessionReducer(state = initialState, action) {
switch (action.type) {
case 'SESSION_REQUEST':
return state.update('isSessionValid', () => false);
case 'SESSION_SUCCESS':
console.log('Reducer: SESSION_SUCCESS');
return state;
case 'SESSION_FAILURE':
console.log('Reducer: SESSION_FAILURE');
return state;
default:
return state;
}
}
export default sessionReducer;
reducers/RootReducer
'use strict';
import {bineReducers} from 'redux';
import sessionReducer from 'reducers/SessionReducer';
const rootReducer = bineReducers({
session: sessionReducer
});
export default rootReducer;
Share
Improve this question
edited Sep 25, 2015 at 11:14
Max
asked Sep 25, 2015 at 9:53
MaxMax
2,5156 gold badges37 silver badges54 bronze badges
8
-
1
can you show what your state looks like? I think because you're not bining the reducers it'll look just like the
initialState
can you also include this too? – Clarkie Commented Sep 25, 2015 at 10:49 - Hi @Clarkie I updated the reducer and put well how I bine the reducers – Max Commented Sep 25, 2015 at 11:15
- 1 have you tried getting it to work without using the immutableJS lib? I've only ever used redux with the immutability helpers from react – Clarkie Commented Sep 25, 2015 at 11:36
-
What version of
redux
andreact-redux
are you running? There might have been issues in pre-1.0 versions. – Dan Abramov Commented Oct 3, 2015 at 14:45 -
2
I'm not sure that this relates directly to the issue you are having, but the way you are logging to the console in
ponentWillMount
is guaranteed to log different results for thesession
prop and thesession
in the store. The call todispatch
will update the store synchronously, but you won't see a newsession
prop until afterponentWillMount
has pleted. Can you verifying this by loggingthis.props.session
in asetTimeout
instead of immediately after the call todispatch
? – lukewestby Commented Oct 4, 2015 at 16:20
2 Answers
Reset to default 5The issue is with the way the session
variable is being logged from props
and from the store. When you dispatch the action to update state it is synchronously updating the store, which is why you see that the store has been updated when you log it directly. However, react-redux won't be able to update props until the call to ponentWillMount
has pleted and React has had a chance to catch up and rerender the ponent with the new state. If you dispatch the action in ponentWillMount
and log the session
prop at a later time you will see that it has changed to reflect the action.
Looks like you don't change state in action handlers in reducer. Only case
with other than return state
code says state.update('isSessionValid', () => false)
— what does it return? If it's the same object as previous state, redux wouldn't change anything because of immutability convention.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742357506a4428735.html
评论列表(0条)