更新不可变数据并在Javascript

时间:2016-12-01 17:32:07

标签: javascript redux immutable.js

所以,我正在使用Immutable对象构建一个React-Redux应用程序,我需要使用从API端点获取的一些数据来更新我的状态。

在添加数据之前,这是我的状态结构

    const state = fromJS({
        tickers: ['AAPL', 'TSLA', 'GOOGL'], 
        data: {
            AAPL: Map(), 
            TSLA: Map(), 
            GOOGL: Map()
        }
    });

我的想法是我获取的数据会进入数据对象

中相应的自动收报机键

以下是我尝试获取数据并进行更新的代码

export function requestAPIData(state, tickerArray){
    return dispatch => {
        return  yahooFinance.historical({
                    symbols: tickerArray, 
                    from: '2012-01-01', 
                    to: '2012-01-05', 
                    period: 'd'
                }, (err, quotes) => {
                    throw new Error('err');
                }).then(result => {
                    addDataToKeysFunction(state, result);
                }).then(() => {
                    console.log(state);
                    dispatch(success());
                })
            }

        }

function addDataToKeysFunction(state, data){
    return new Promise ((resolve, reject) => {
        for(let key in data){
            console.log(data[key]);
            state.setIn(['data', key], data[key]);
        }
        resolve();
    })
}

所以,这就是让我感到困惑的地方。如果我只是在状态对象上调用state.setIn,它只会暂时更新,因为在您返回状态(?)之前,Immutable对象不会更新。但是,我也要回复一个需要解决或拒绝的承诺。如何确保状态得到更新并解决承诺。

我对处理不可变数据结构相对较新,所以如果有一些我不知道的事情,请指出它。此外,如果使用回调是完成此操作的唯一方法,那也很好。

2 个答案:

答案 0 :(得分:1)

好的,所以我找到了答案。出于某种原因,作为promise调用的resolve()的一部分返回数据会引发错误,但在回调中返回它可以正常工作。

export function requestAPIData(state, tickerArray){
    return dispatch => {
        return  yahooFinance.historical({
                    symbols: tickerArray, 
                    from: '2012-01-01', 
                    to: '2012-01-05', 
                    period: 'd'
                }, (err, quotes) => {
                    throw new Error('err');
                }).then(result => {
                    addDataToKeysFunction(state, result, function(return_data){
                        console.log(return_data);
                    });
                })
            }

        }

function addDataToKeysFunction(state, data, done){
    let new_state = state;
    for(let key in data){
        new_state = state.setIn(['data', key], data[key]);
        state = state.merge(new_state);
    }
    done(state);
}

答案 1 :(得分:0)

您的代码存在一些问题,坦率地说,这表明对Redux存在根本性的误解。就像其他人在我之前所表达的那样,我建议我们回去并花一些时间阅读Redux文档。

以上代码的一些评论:

  • Dispatch应该只接受向商店传达意图的普通JS对象(以及通过扩展名传递减速器)。
  • 只要您的应用程序改变其状态,该逻辑应该在其reducer中发生。在这里,你似乎是在减速器之外改变状态。
  • 当您将异步操作与Redux混合使用时,您可能应该使用其他库,如Thunk。查看Redux文档以获取异步配方。