如何在Redux Reducer中保持先前状态并将新状态添加到先前状态?

时间:2018-10-31 23:45:10

标签: reactjs redux

以下是我的减速器之一。在功能applySetRandomImages中,我想访问randomImages的先前状态,以在先前的状态下添加新的状态randomImages

我该怎么做? Redux中的reducer函数是否为此提供了一些回调函数?还是我应该自己实施?

// ACTIONS
const SET_RANDOM_IMAGES = "SET_RANDOM_IMAGES";

// ACTION CREATORS
function setRandomImages(randomImages) {
  return {
    type: SET_RANDOM_IMAGES,
    randomImages
  };
}

// API ACTIONS
function getRandomImages(page) {
  return (dispatch, getState) => {
    fetch(`/boutiques/random-images/?page=${page}`)
      .then(response => response.json())
      .then(json => dispatch(setRandomImages(json.results)))
      .catch(err => console.log(err));
  };
}

// INITIAL STATE
const initialState = {};

// REDUCER
function reducer(state = initialState, action) {
  switch (action.type) {
    case SET_RANDOM_IMAGES:
      return applySetRandomImages(state, action);
    default:
      return state;
  }
}

// REDUCER FUNCTIONS
function applySetRandomImages(state, action) {
  const { randomImages } = action;
  return {
    ...state,
    randomImages    <--- I need to merge the randomImages with a new state of randomImages
  };
}

// EXPORTS
const actionCreators = {
  getRandomImages,
};
export { actionCreators };

// DEFAULT REDUCER EXPORTS
export default reducer;

3 个答案:

答案 0 :(得分:1)

您可以通过将旧状态和新状态散布到新数组中来合并randomImages

function applySetRandomImages(state, action) {
  const { randomImages } = action;
  return {
    ...state,
    randomImages: [...state.randomImages, ...randomImages],
  };
}

答案 1 :(得分:0)

actionsreducerstypes分离到各自的文件夹中。

types / index.js

export const SET_RANDOM_IMAGES = "SET_RANDOM_IMAGES";

actions / imageActions.js

import * as types from '../types';

export const getRandomImages = page => dispatch => (
  fetch(`/boutiques/random-images/?page=${page}`)
    .then(response => response.json())
    .then(json => dispatch({ type: types.SET_RANDOM_IMAGES, payload: json.results })))
    .catch(err => console.log(err))
)

在组件内,您将connect还原为状态(state.imagesstate.images.collection),并dispatch进入actiongetRandomImages) :

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getRandomImages } from '../actions/imageActions';

class Example extends Component {

   componentDidMount = () => this.props.getRandomImages(); // dispatches action creator

   render = () => (
       <div>
         { /* 
             The props below are redux state passed into 
             the component via the connect function
         */ }
         {this.props.images.map(image => (
           <img src={image.src} alt="image.name" />
         ))}
         {this.props.collection.map(image => (
           <img src={image.src} alt="image.name" />
         ))}
       </div>
   )
}

export default connect(state => ({ 
  images: state.images, // pulled from redux state (state.images => this.props.images)
  collection: state.images.collection // pulled from redux state (state.images.collection => this.props.images.collection)
}), { getRandomImages})(Example)

然后它将触发AJAX请求,然后向您的type返回payloadreducer

reducers / index.js

import * as types from '../types'

// overwrite images for each successful fetch request
const imageReducer(state={}, {type, payload}) {
  switch (type) {
    // spread out any previous state, then spread out the payload (json.results)
    case types.SET_RANDOM_IMAGES: return { ...state, ...payload }
    default: return state;
  }
}

// or append images on each successful fetch request...
const imageReducer(state={}, {type, payload}) {
  switch (type) {
    case types.SET_RANDOM_IMAGES: 
      return { 
        ...state,  // spread out any previous state
        collection: [ 
          ...state.collection, //  then spread out any previous "collection" state, 
          ...payload // then spread/append the payload (json.results) 
        ]
      }
    default: return state;
  }
}

export default combineReducers({
  images: imageReducer
});

然后,reducer将散布任何先前的imageReducer状态,然后通过res.resultspayload附加到该状态。现在它在redux中以state.imagesstate.images.collection的形式存在。然后将其从redux状态拉入this.props.imagesthis.props.images.collection的上方组件。

答案 2 :(得分:0)

  

我想访问randomImages的先前状态,以添加具有先前状态的randomImages新状态

return {
    ...state,
    ...randomImages
};

如果先前的state是:

{
    a: 1,
    b: 2,
    c: 3
}

randomImages是:

{
    d: 4,
    e: 5
}

然后返回的新状态将是

{
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: 5
}