Redux:如何将项添加到Array,并返回包含所有项的Array

时间:2017-06-29 21:34:08

标签: javascript reactjs redux react-redux bitcoin

我在我的React应用程序中使用Redux,目前只有一个减速器用于加密货币组合。只是一堆硬币。

当我第一次收到一个预期的1个对象的数组时,我会调度我的ADD_COIN操作。然而,当我再次在另一个硬币上调用dispatch时,它会再次返回Array,但仍然只有1个项目,即所选的最新硬币。

如何重新编写这个以使用所有添加的硬币返回更新的数组?

添加第一枚硬币 enter image description here

添加了第二枚硬币,预计会看到一个包含2个对象的数组: enter image description here

index.js商店代码

const store = createStore(reducer, compose(
    applyMiddleware(thunk),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
));

reducer文件

import { combineReducers } from 'redux'
import portfolio from './portfolio'

export default combineReducers({
    portfolio
});

动作文件

import * as R from 'ramda'
import * as api from '../../services/api'
import { addToPortfolio, getPortfolio } from '../../services/coinFactory'

export const ADD_COIN = 'ADD_COIN'

export function addCoin(coin) {
    return dispatch =>
        api.getCoin(coin)
            .then((res) => addToPortfolio(R.head(res.data)))
            .then((portfolio) => dispatch(add(portfolio)));
}

//action creator
export function add(portfolio) {
    return {
        type: ADD_COIN,
        portfolio
    }
}

投资组合减速机

import { ADD_COIN } from './actions'

const initialState = [];

export default (state = initialState, action) => {
    switch(action.type) {
        case ADD_COIN:
            return action.portfolio;
        default:
            return state;
    }
}

最后是具有Array

的coinFactory.js
import * as R from 'ramda'
import local_coins from '../coins.json'

export const storage = {
    coins: local_coins,
    portfolio: []
};

export const getPortfolio = () => storage.portfolio;

export const addToPortfolio = (coin) => {
    storage.portfolio.push(coin);
    return getPortfolio();
};

2 个答案:

答案 0 :(得分:7)

不要使用.push改变您的initialState,而是将您的上一个状态“复制”为有意义的新状态

import { ADD_COIN } from './actions'

const initialState = [];

export default (state = initialState, action) => {
    switch(action.type) {
        case ADD_COIN:
            return [...state, action.portfolio]; // same as state.concat(action.portfolio)
        default:
            return state;
    }
}

答案 1 :(得分:1)

我想通了,我错误地尝试使用2种不同的设计模式。 Redux的工厂模式......实际上并不坏,但它让我犯了这个错误。

import { ADD_COIN } from './actions'

const initialState = [];

export default (state = initialState, action) => {
    switch(action.type) {
        case ADD_COIN:
            return initialState.push(action.portfolio);
        default:
            return state;
    }
}

initialState 被认为是我的投资组合数组。 所以在动作ADD_COIN的情况下,我需要将它推入该数组,而不是我工厂的数组(虽然我想我可以使用工厂数组并将其设置为initialState)

然后在我的行动中,我只发出了硬币,而不是已经在另一个阵列中的硬币。

import * as R from 'ramda'
import * as api from '../../services/api'

export const ADD_COIN = 'ADD_COIN'

export function addCoin(coin) {
    return dispatch =>
        api.getCoin(coin)
            .then((res) => R.head(res.data))
            .then((remote_coin) => dispatch(add(remote_coin)));
}

// action creator
export function add(portfolio) {
    return {
        type: ADD_COIN,
        portfolio
    }
}

现在,Portfolio Array的状态正确更新

enter image description here

enter image description here

如果有人对此有更好的描述答案,我会标记他们的答案,而不是这个。