2015-09-25 147 views
3

我使用Redux作为Flux替代方案,而React作为视图层。我的应用程序的ReactReduxreact-reduxconnect()方法绑定。 运行应用程序时,它会在组件挂载并且redux返回正确的状态时调度该操作。但redux-logger登录到商店用新状态更新的控制台中,在组件中检查this.props.session时它仍显示旧状态。我猜测我没有正确使用connect方法,但是我也无法定义它的问题。有人有一个想法是怎么回事?React-redux,连接功能不会更新新数据的状态

容器/应用

'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); 
    } 
    componentWillMount() { 
    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.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))); 
    }; 
} 

减速器/ 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; 

级减速器/ RootReducer

'use strict'; 

import {combineReducers} from 'redux'; 
import sessionReducer from 'reducers/SessionReducer'; 

const rootReducer = combineReducers({ 
    session: sessionReducer 
}); 

export default rootReducer; 
+1

你能显示你的状态是什么样子吗?我认为,因为你没有合并减速器,它看起来就像'initialState',你是否也可以包含这个呢? – Clarkie

+0

嗨@Clarkie我更新了减速机,并把我如何结合减速机 – Max

+1

你有没有尝试让它在没有使用immutableJS库的情况下工作?我只用过[immutability helpers](https://facebook.github.io/react/docs/update.html)中的redux反应 – Clarkie

回答

5

问题出在session变量从props和商店中记录的方式。当您将动作分派到更新状态时,它会同步更新商店,这就是为什么您在直接登录时发现商店已更新的原因。然而,react-redux将无法更新道具,直到componentWillMount的调用完成,并且React有机会追赶并重新渲染具有新状态的组件。如果您在componentWillMount中发送操作并在稍后记录session prop,则会看到它已更改为反映该操作。

0

看起来你不行动处理器在减速改变状态。只有casereturn state以外的代码表示state.update('isSessionValid',() => false) - 它返回的是什么?如果它与之前的状态是相同的对象,那么由于不可变约定,redux不会改变任何内容。

+0

'state'是'ImmutableJs'对象,'update'是'Map'类的方法。这里是[完整文档](https://facebook.github.io/immutable-js/docs/#/Map/update)。基本上,'update'函数将返回新的'Map'对象与'isSessionValid'到假,最初它是'null' – Max

+0

@Max,并且在使用此字段的客户端代码中,您是否明确区分了null和false?因为JavaScript中的'compute to false',这看起来像可能的麻烦 –