개체 내에서 배열을 푸시하는 동안 돌연변이를 방지하는 방법
나는 회사를 가지고 있는 물건을 가지고 있고 회사 안에는 여러 팀이 있다.
company: {
teams: [
{
name: 'test team',
description: 'dddd',
team_manager: null,
company: '592577d5b591966c8e535865',
permalink: 'test-team',
createdAt: '2017-05-30T07:38:58.983Z',
updatedAt: '2017-05-30T07:38:58.983Z',
id: '592d219277923054118e7299'
}
],
name: 'test company2',
createdAt: '2017-05-24T12:08:53.418Z',
updatedAt: '2017-05-24T12:08:53.419Z',
id: '592577d5b591966c8e535865'
}
}
한 팀이 추가되면, 나는 팀을 배열로 밀어넣기 위해 이 환원기를 사용하고 있다.
case types.ADD_TEAM_SUCCESS :
return Object.assign({}, state, state.teams.push(action.newTeam));
그러나 콘솔에서 다음과 같은 경고를 받고 있다.
'오류: 다음 경로에서 디스패치 내부에서 상태 돌연변이가 감지됨:company.teams.0
'
객체를 닫고 새로운 팀을 어레이에 밀어넣기 위한 올바른 방법은 무엇인가?
es2015를 사용하고 있다면 다음과 같은 것을 할 수 있다.
return Object.assign({}, state, { teams: [...state.teams, action.newTeam] });
개체를 다음으로 직접 푸시하는 경우state.teams
먼저 복사하고 대신 그것을 사용해야 한다.스프레드 연산자를 사용할 수 없는 경우 상태를 슬라이스할 수 있다.팀을 새로운 변수로 만들고 대신 그 쪽으로 밀어붙인다.
Object.assign() 앞에 설명된 것처럼 개체의 복제 작업이 깊지 않음.
내 제안은 당신의 상점을 정상화하고 회사와 팀 두 개의 상점으로 나누는 것이다.
combinateReducer를 사용하여 이것을 하나의 저장소에 연결하는 것보다 당신은 환원기를 단순화하고 코드를 더 읽기 쉽게 만들 것이다.또한 당신은 공연으로 노는 것 이상을 할 수 있다.
내 말은...만약 당신이 단지 회사와 함께 일하는 컴포넌트를 가지게 될 것이고 당신은 팀내 변화를 가지게 될 것이고 당신은 쉽게 재입사를 피할 것이다.
Dan Abramov grate 비디오 튜토리얼 확인 Redx: 상태 셰이프 표준화
어떻게든 그렇게 하겠다(타입체 코드는 미안하다)
export interface ICompanyItem {
name: string;
id: string;
createdAt: Date;
updatedAt: Date;
}
export interface ITeamItem {
id: string;
companyId: string
name: string;
description: string;
team_manager: string;
createdAt: Date;
updatedAt: Date;
}
export interface ICompaniesState {
items: { [id: string]: ICompanyItem };
}
export interface ITeamsState {
items: { [id: string]: ITeamItem };
}
export const teamsReducer: Reducer<ITeamsState> = (state: ITeamsState, action: Action) => {
if (isActionType(action, AddNewTeamItem)) {
let itemsClone: { [id: string]: ITeamItem } = { ...state.items, [action.id]: action.team };
return {
...state,
items: itemsClone
};
}
return state || unloadedState;
};
문제는 이다Object.assign()
개체 [1]의 깊은 클론을 수행하지 마십시오("딥 클론에 대한 경고" 참조).
스택에 lodash와 같은 유틸리티 라이브러리가 없는 경우 JSON 인코딩 및 디코딩을 사용하여 작업을 완료할 수 있다.
case types.ADD_TEAM_SUCCESS:
let stateCopy = JSON.parse(JSON.stringify(state));
state.teams.push(action.newTeam);
return state;
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
'programing' 카테고리의 다른 글
TypeScript React.FC 혼선 (0) | 2022.03.15 |
---|---|
VueJs 개체 키/값이 v-for 루프에서 반응하지 않음 (0) | 2022.03.15 |
css 모듈을 사용하여 둘 이상의 스타일 이름을 정의하는 방법 (0) | 2022.03.15 |
이전 리액터-라우터(# 포함)를 BrowserRouter로 리디렉션하는 방법? (0) | 2022.03.15 |
여러 이미지를 Python과 수평으로 결합 (0) | 2022.03.15 |