React 기본 redux의 감속기에서 배열에 요소를 어떻게 추가합니까?


140

arr[]감속기의 redux 상태 배열 에 요소를 어떻게 추가 합니까? 나는 이것을하고있다.

import {ADD_ITEM} from '../Actions/UserActions'
const initialUserState = {
    arr:[]
}

export default function userState(state = initialUserState, action)
{
    console.log(arr);
    switch (action.type)
    {
        case ADD_ITEM: 
            return { 
                      ...state,
                      arr: state.arr.push([action.newItem])
                   }

        default:
            return state
    }
}

답변:


363

돌연변이없이 배열에 항목을 추가하는 두 가지 옵션

case ADD_ITEM :
    return { 
        ...state,
        arr: [...state.arr, action.newItem]
    }

또는

case ADD_ITEM :
    return { 
        ...state,
        arr: state.arr.concat(action.newItem)
    }

1
어느 것이 선호되어야합니까?
sapht

19
ES6에서 코드를 작성하는 경우 @sapht보다 읽기 쉽고 우아한 IMO 인 첫 번째 코드를 선호합니다.
Yadhu Kiran

5
또한 첫 번째는 순수하고 두 번째는 순수하지 않습니다. Redux 문서에서 : "리듀서를 순수하게 유지하는 것이 매우 중요합니다. 리듀서 내에서 절대로하지 말아야 할 일 : 1. 인수를 변경하십시오; 2. API 호출 및 라우팅 전환과 같은 부작용을 수행하십시오. 예 : Date.now () 또는 Math.random (). "
매력적인 로봇

안녕하세요, @YadhuKiran 왜 우리가 배열의 두 번째 색인에 새로운 가치를 추가하는지 이해할 수 없었습니까? arr: [...state.arr, why here?]
올리버 D

@OliverD, 위와 같이 스프레드 구문 을 사용하면 두 번째 인덱스가 아니라 마지막 인덱스에 요소를 삽입합니다. 이와 반대로 [action.newItem, ...state.arr], 첫 번째 위치에 요소를 삽입합니다.
Yadhu Kiran

22

push배열을 반환하지 않지만 그 길이 ( docs )를 반환하므로 배열을 길이로 바꾸고 가지고있는 유일한 참조를 잃어 버립니다. 이 시도:

import {ADD_ITEM} from '../Actions/UserActions'
const initialUserState = {

    arr:[]
}

export default function userState(state = initialUserState, action){
     console.log(arr);
     switch (action.type){
        case ADD_ITEM :
          return { 
             ...state,
             arr:[...state.arr, action.newItem]
        }

        default:return state
     }
}

1
Object.assign상태 내 배열의 변경에 대해 누구 든지이 질문에 대답 할 수 있습니까 ?
Vennesa

2
왜 필요한 Object.assign가요? 객체에 사용되며 본질적으로 동일합니다. 당신은 어디에서 arr:[...state.arr, action.newItem]사용할 수있는 obj: Object.assign({}, state.obj, action.newItem것을 제공, objnewItem개체입니다. 전체 주 Object.assign({}, state, {arr: [..state.arr, action.newItem]})
에이

1
@ martinarroyo, 고마워서 그렇게 var obj = { isLoading: true, data: ['a', 'b', 'c', 'd'] } var newObj = Object.assign({}, obj, { data: [...obj.data, 'e'] });했습니다 { isLoading: true, data: [ 'a', 'b', 'c', 'd', 'e' ] }. 그러나 스프레드 연산자없이 Object.assign을 사용하여 동일한 결과를 생성하고 싶었습니다. 가능합니까?
Vennesa

1
@Vennesa [].concat(obj.data, ['e'])ES6 기능을 사용하지 않으려면을 (를)로 바꿀 수 있다고 생각 합니다. Object.assign은 객체를위한 것이며, 배열에서 사용할 때 오류가 발생하지 않지만 결과는 배열의 연결이 아닙니다. 당신이하려고하면 Object.assign({}, [1, 2, 3], [4]), 당신은 얻을 [4, 2, 3]결과.
martinarroyo

13

배열의 특정 위치에 삽입해야하는 경우 다음을 수행 할 수 있습니다.

case ADD_ITEM :
    return { 
        ...state,
        arr: [
            ...state.arr.slice(0, action.pos),
            action.newItem,
            ...state.arr.slice(action.pos),
        ],
    }

나는 여기에서 우연히 발견되었지만 ...이 대답은 위의 질문에 정확하게 맞지 않습니다. 그럼에도 불구하고, 그것은 내가 찾던 것입니다. 배열의 특정 인덱스에 객체를 삽입하는 방법을 찾고있었습니다. 따라서 나는 대답을 투표했다. 매우 도움이되었고 시간을 절약 할 수있었습니다. 감사!
omostan

0

샘플이 있습니다

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

var initialState = {
  changedValues: {}
};
const quickEdit = (state = initialState, action) => {

  switch (action.type) {

    case types.PRODUCT_QUICKEDIT:
      {
        const item = action.item;
        const changedValues = {
          ...state.changedValues,
          [item.id]: item,
        };

        return {
          ...state,
          loading: true,
          changedValues: changedValues,
        };
      }
    default:
      {
        return state;
      }
  }
};

export default quickEdit;

1
설명 추가
SPatel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.