最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Redux: How to add item to Array, and return Array with all items added - Stack Overflow

programmeradmin3浏览0评论

I'm using Redux in my React App, currently only have 1 reducer at the moment for a Portfolio of cryptocurrencies. Just an array of coins.

When I dispatch my ADD_COIN action the first time I get back an Array of 1 object which is expected. However when I call dispatch again on another coin it returns the Array again, but still only with 1 item, the latest coin that was selected.

How would this need to be re-written to return back the updated Array with all added coins?

1st coin added

2nd coin added, expected to see an Array with 2 objects:

index.js the store code

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

The reducer file

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

export default combineReducers({
    portfolio
});

The actions file

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
    }
}

The Portfolio reducer

import { ADD_COIN } from './actions'

const initialState = [];

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

Finally the coinFactory.js which has the Array

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();
};

I'm using Redux in my React App, currently only have 1 reducer at the moment for a Portfolio of cryptocurrencies. Just an array of coins.

When I dispatch my ADD_COIN action the first time I get back an Array of 1 object which is expected. However when I call dispatch again on another coin it returns the Array again, but still only with 1 item, the latest coin that was selected.

How would this need to be re-written to return back the updated Array with all added coins?

1st coin added

2nd coin added, expected to see an Array with 2 objects:

index.js the store code

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

The reducer file

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

export default combineReducers({
    portfolio
});

The actions file

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
    }
}

The Portfolio reducer

import { ADD_COIN } from './actions'

const initialState = [];

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

Finally the coinFactory.js which has the Array

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();
};
Share Improve this question asked Jun 29, 2017 at 21:34 Leon GabanLeon Gaban 39k122 gold badges348 silver badges549 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 15

Instead of mutating your initialState with .push, "copy" your last state into meaningful new state

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;
    }
}

I figured it out, I was incorrectly trying to use 2 different design patterns. The factory pattern with Redux... not actually bad, but it made me make this mistake.

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 is suppose to be my Portfolio array. So in the case of action ADD_COIN, I need to push it into that array, not the one from my factory (though I guess I could use the factory Array and set it to initialState)

Then in my actions I sent out just the coin, not a coin already inside of another Array.

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
    }
}

Now the state of the Portfolio Array updates correctly

If someone has a better more description answer to this I'll mark their answer instead of this.

发布评论

评论列表(0)

  1. 暂无评论