javascript - React/Redux 状态在第二次操作调用时为空

标签 javascript node.js reactjs redux react-redux

我对 React/Redux 还是比较陌生,如果这是一个简单的问题,我深表歉意,但我还没有找到解决方案。

我有两个 Action :

// DESTINATIONS
// ==============================================

export const DESTINATION_REQUEST = 'DESTINATION_REQUEST';
export const DESTINATION_SUCCESS = 'DESTINATION_SUCCESS';
export const DESTINATION_FAILURE = 'DESTINATION_FAILURE';

export function loadDestination (params, query) {

    const state = params.state ? `/${params.state}` : '';
    const region = params.region ? `/${params.region}` : '';
    const area = params.area ? `/${params.area}` : '';

    return (dispatch) => {
        return api('location', {url: `/accommodation${state}${region}${area}`}).then((response) => {
            const destination = formatDestinationData(response);

            dispatch({
                type: DESTINATION_SUCCESS,
                destination
            });
        });
    };
}





// PROPERTIES
// ==============================================

export const PROPERTIES_REQUEST = 'PROPERTIES_REQUEST';
export const PROPERTIES_SUCCESS = 'PROPERTIES_SUCCESS';
export const PROPERTIES_FAILURE = 'PROPERTIES_FAILURE';

export function loadProperties (params, query, rows = 24) {

    return (dispatch, getState) => {

        console.log(getState());

        return api('search', {locationId: xxxxxx, rows: rows}).then((response) => {
            const properties = response.results.map(formatPropertiesData);

            dispatch({
                type: PROPERTIES_SUCCESS,
                properties
            });
        });
    };
}

这些与它们的相关 reducer 相结合:

// DESTINATIONS REDUCERS
// ==============================================

export default function destination (state = [], action) {
    switch (action.type) {
    case DESTINATION_SUCCESS:
        return action.destination;
    default:
        return state;
    }
}





// PROPERTIES REDUCERS
// ==============================================

export default function properties (state = [], action) {
    switch (action.type) {
    case PROPERTIES_SUCCESS:
        return action.properties;
    default:
        return state;
    }
}

并且它们是从组件内部调用的(connectDataFetchers 循环遍历调用的操作并将它们返回到组件以进行服务器端渲染):

// PROPTYPES
// ==============================================

Search.propTypes = {
    destination: PropTypes.object.isRequired,
    properties: PropTypes.array.isRequired
};





// ACTIONS
// ==============================================

function mapStateToProps ({destination, properties}) {
    return {destination, properties};
}





// CONNECT & EXPORT
// ==============================================

export default connect(mapStateToProps)(
    connectDataFetchers(Search, [loadDestination, loadProperties])
);

export default function connectDataFetchers (Component, actionCreators) {
    return class DataFetchersWrapper extends React.Component {
        static propTypes = {
            dispatch: React.PropTypes.func.isRequired,
            location: React.PropTypes.object.isRequired,
            params: React.PropTypes.object.isRequired
        };
        
        static fetchData (dispatch, params = {}, query = {}) {
            return Promise.all(
                actionCreators.map((actionCreator) => dispatch(actionCreator(params, query)))
            );
        }

        componentDidMount () {
            DataFetchersWrapper.fetchData(
                this.props.dispatch,
                this.props.params,
                this.props.location.query
            );
        }

        render () {
            return (
                <Component {...this.props} />
            );
        }
    };
}

我需要运行第一个操作 (loadDestination),它将返回一个 ID,然后需要传递给第二个操作以加载具有该位置 ID 的属性。

如果我硬编码一个 locationID 这工作正常,但如果我尝试通过 getState() 访问 loadProperties 中的状态然后它返回 { destination: [ ], 属性: [] }.

有没有办法通过状态访问第一个操作的值?

解决方案

按照@pierrepinard_2 的建议设法让它工作

我创建了一个新 Action ,它按我需要的顺序分派(dispatch)其他两个 Action :

// SEARCH
// ==============================================

export function loadSearch (params, query) {
    
    return (dispatch) => {
        return dispatch(
            loadDestination(params, query)
        ).then(() => {
            return dispatch(
                loadProperties(params, query)
            )
        })
    }
}

// DESTINATIONS
// ==============================================

export const DESTINATION_REQUEST = 'DESTINATION_REQUEST';
export const DESTINATION_SUCCESS = 'DESTINATION_SUCCESS';
export const DESTINATION_FAILURE = 'DESTINATION_FAILURE';

export function loadDestination (params, query) {

    const state = params.state ? `/${params.state}` : '';
    const region = params.region ? `/${params.region}` : '';
    const area = params.area ? `/${params.area}` : '';

    return (dispatch) => {
        return api('location', {url: `/accommodation${state}${region}${area}`}).then((response) => {
            const destination = formatDestinationData(response);
            
            dispatch({
                type: DESTINATION_SUCCESS,
                destination
            });
        });
    };
}
  
  // PROPERTIES
// ==============================================

export const PROPERTIES_REQUEST = 'PROPERTIES_REQUEST';
export const PROPERTIES_SUCCESS = 'PROPERTIES_SUCCESS';
export const PROPERTIES_FAILURE = 'PROPERTIES_FAILURE';

export function loadProperties (params, query, rows = 24) {

    return (dispatch, getState) => {
        return api('search', {locationId: getState().destination.id, rows: rows}).then((response) => {
            const properties = response.results.map(formatPropertiesData);

            dispatch({
                type: PROPERTIES_SUCCESS,
                properties
            });
        });
    };
}

然后在组件中我只请求一个 Action :

export default connect(mapStateToProps)(
    connectDataFetchers(Search, [loadSearch])
);

最佳答案

您在 fetchData() 方法中使用 Promise.all():您的操作是并行分派(dispatch)的,而不是一个接一个地分派(dispatch)。

为确保您先调用目标再调用属性,您应该为搜索组件创建一个特定的异步操作创建器。在这种情况下,这个异步操作创建者将实现您需要的连续请求。

关于javascript - React/Redux 状态在第二次操作调用时为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36763497/

相关文章:

javascript - 使用 setInterval 每 60 秒保存一次表单不起作用

performance - 从 Node.js 释放所需的模块

reactjs - React 未捕获引用错误 - 对象/类未定义

reactjs - JSX 不会将表达式中的整数计算为 bool 值

javascript - 在 React 组件的类之外编写函数

javascript - 如何将 angularjs 指令绑定(bind)到链接函数中定义的 d3js 节点

javascript - 水平画廊 - 滚动和触摸

javascript - 如何在不连接的情况下在 JavaScript 中的字符串中插入变量?

javascript - 使用递归搜索对对象中的数组进行排序

node.js - 复杂的过滤器 Sequelize js