Как я могу сохранить предыдущее состояние и добавить новое состояние к предыдущему состоянию в редукторах Redux? - PullRequest
0 голосов
/ 01 ноября 2018

Ниже приведен один из моих редукторов. В функции applySetRandomImages я хочу получить доступ к предыдущему состоянию randomImages, чтобы добавить новое состояние randomImages с предыдущим состоянием.

Как я могу это сделать? Функция редуктора в Redux предоставляет для этого некоторую функцию обратного вызова? или я должен реализовать это самостоятельно?

// 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 голосов
/ 01 ноября 2018

Вы можете объединить randomImages, распространяя старое состояние и новое в новый массив:

function applySetRandomImages(state, action) {
  const { randomImages } = action;
  return {
    ...state,
    randomImages: [...state.randomImages, ...randomImages],
  };
}
0 голосов
/ 01 ноября 2018

Я хочу получить доступ к предыдущему состоянию 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
}
0 голосов
/ 01 ноября 2018

Разделите actions, reducers и types в свои собственные папки.

типы / index.js

export const SET_RANDOM_IMAGES = "SET_RANDOM_IMAGES";

действия / 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.images или state.images.collection) и dispatch action (getRandomImages):

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 и payload вашему reducer:

редукторы / 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
});

Затем редуктор распространит любое предыдущее состояние imageReducer, а затем добавит к нему res.results через payload. Теперь он существует в редуксе как state.images или state.images.collection. Затем он выводится из состояния избыточности и в компонент выше как this.props.images или this.props.images.collection.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...