React-Redux: Копирование массива из состояния в функции Reducer, чтобы вы могли изменить его - PullRequest
2 голосов
/ 17 апреля 2020

Я работаю над приложением React и использую Redux для хранения состояния. У меня есть следующий код:

menu.reducer. js:

import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK } from './menu.types';

const INITIAL_STATE = []


export default (state = INITIAL_STATE, action) => {
    switch (action.type) {

        case INCREASE_CATEGORY_RANK: {
            console.log("Printing the state");
            console.log(state);
            return state.map(category => {
                if (category._id === action.payload._id) {
                    const oldrank = category.rank;
                    return {
                        ...category,
                        rank: oldrank + 1
                    }
                } else {
                    return category;
                }
            })
        }
        case DECREASE_CATEGORY_RANK: {
            return state.map(category => {
                if (category._id === action.payload._id && category.rank !== -1) {
                    const oldrank = category.rank;
                    return {
                        ...category,
                        rank: oldrank - 1
                    }
                } else {
                    return category;
                }
            })
        }
        default:
            return state;
    }
}

menu.types. js:

export const INCREASE_CATEGORY_RANK = "INCREASE_CATEGORY_RANK";
export const DECREASE_CATEGORY_RANK = "DECREASE_CATEGORY_RANK";

menu.actions. js:

import { apiUrl, apiConfig } from '../../util/api';
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK } from './menu.types';

export const getMenu = () => async dispatch => {
    const response = await fetch(`${apiUrl}/menu`);
    if (response.ok) {
        const menuData = await response.json();
        dispatch({ type: GET_MENU, payload: menuData })
    }
}

export const increaseCategoryRank = category => dispatch => {
    dispatch({ type: INCREASE_CATEGORY_RANK, payload: category })
}

export const decreaseCategoryRank = category => dispatch => {
    dispatch({ type: DECREASE_CATEGORY_RANK, payload: category })
}

category-arrow.component.jsx:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { increaseCategoryRank, decreaseCategoryRank } from '../../redux/menu/menu.actions';
import './category-arrows.styles.scss';

class CategoryArrows extends Component {

    render() {

        const { category, increaseCategoryRank, decreaseCategoryRank } = this.props;

        return (
            <div class="arrows-container">
                <div class="up-arrow" onClick={() => this.props.increaseCategoryRank(category)}></div>
                <div class="category-rank">
                    <p>{category.rank}</p>
                </div>
                <div class="down-arrow" onClick={() => this.props.decreaseCategoryRank(category)}></div>
            </div>
        )
    }
}

export default connect(null, { increaseCategoryRank, decreaseCategoryRank } )(CategoryArrows);

Для моей функции Reducer начальное состояние извлекается из базы данных. Код Редуктора работает с массивом menu, который представляет собой массив объектов:

enter image description here

Я хочу отсортировать этот массив menu по к значению свойства rank, а также поменяйте местами элементы в массиве на основе определенных условий. Чтобы сделать это, я должен сначала скопировать массив, внести изменения, а затем переназначить состояние этому новому массиву.

Я попытался console.log () состояние, чтобы увидеть, что это такое в моем редукторе функция. Когда я нажимаю * div 1027 * в category-arrows.component.jsx, отправляется действие INCREASE_CATEGORY_RANK. Когда я проверяю Консоль, я получаю следующее:

enter image description here

Я не уверен, как скопировать массив меню из состояния в моей функции Reducer, чтобы что я могу внести изменения, которые я хочу, и затем переназначить этот массив в состояние. Любые идеи приветствуются.

1 Ответ

1 голос
/ 17 апреля 2020

Чтобы скопировать массив без изменения оригинала (при условии, что это редуктор):

// make a copy of the original
const updatedArray = [...state.menu]

// find the object you want to modify (this is a generic example)
let selectedItem = updatedArray.findIndex((element) => {
  return element.id === action.payload._id
}

// make your modification (let's pretend you wanted to update the name property)
updatedArray[selectedItem].name = 'Changed Name'

// merge the original state and set the menu property to the updatedArray
return {
  ...state,
  menu: updatedArray
}

Это проблема, которую вы пытаетесь решить (копирование исходного состояния и его изменение)?

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