[ReactJS] Immutability
10305 ワード
Immutability
不変性:値またはステータスを変更できないことを示す値
状態を変えて、状態を変えないで欲しい状態を変えて、これは言いにくいです...
必要な値を変換して使用する場合は、値のコピーを作成する必要があります.
💡1.探すきっかけ
// 리듀서
function todos(state = initialState, action) {
switch (action.type) {
case CHANGE_INPUT:
return {
...state,
input: action.input
};
case INSERT:
return {
...state,
todos: state.todos.concat(action.todo)
};
case TOGGLE:
return {
...state,
todos: state.todos.map(todo =>
todo.id === action.id ? { ...todo, done: !todo.done } : todo
)
};
case REMOVE:
return {
...state,
todos: state.todos.filter(todo => todo.id !== action.id )
};
default:
return state;
}
}
// 리듀서
// redux-actions 라이브러리 사용
const todos = handleActions({
[INSERT]: (state,action) => ({...state, todos: state.todos.concat(action.payload)}),
[CHANGE_INPUT]: (state,action) => ({...state, input: action.payload}),
[REMOVE]: (state,action) => ({...state, todos: state.todos.filter((todo) => (todo.id !== action.payload))}),
[TOGGLE]: (state,{payload: id}) => ({...state, todos: state.todos.map((todo) => todo.id === id ? {...todo,done: !todo.done} : todo)})
}, initialState)
// 리듀서
// immer 사용
const todos = handleActions(
{
[CHANGE_INPUT]: (state, { payload: input }) =>
produce(state, draft => {
draft.input = input;
}),
[INSERT]: (state, { payload: todo }) =>
produce(state, draft => {
draft.todos.push(todo);
}),
[TOGGLE]: (state, { payload: id }) =>
produce(state, draft => {
const todo = draft.todos.find(todo => todo.id === id);
todo.done = !todo.done;
}),
[REMOVE]: (state, { payload: id }) =>
produce(state, draft => {
const index = draft.todos.findIndex(todo => todo.id === id);
draft.todos.splice(index, 1);
})
},
initialState,
);
💡2.Reactのデフォルト属性
リアクターは浅い比較で新しい値かどうかを判断し、新しい値であれば再レンダリングします.
浅い比較とは、オブジェクト、配列、関数などの参照タイプの実際の内部値を比較するのではなく、同じ参照(同じメモリ値を使用するかどうか)を比較することです.
次のシーンを見て、なぜ反応器でstate値を直接変更できないのかを感じてみましょう.
state.push('a')
を介してステータス配列に直接アクセスして要素を追加します.上記の理由から、新しいオブジェクトまたは配列を作成して新しい参照値を作成し、反応器に以前とは異なる参照値であることを通知する必要があります.
2-1)複製オブジェクト(配列)例
const user = { name: 'chichi', age: 30 }
const copyUser = user; // 배열의 복사가 아니라 같은 참조 값을 가짐
user.age += 1;
console.log('user: ', user);
console.log('copyUser: ', copyUser);
/*
user: { name: 'chichi', age: 31 }
copyUser: { name: 'chichi', age: 31 }
*/
const arr = ['b', 'c', 'd'];
const copyArr = arr;
arr.push('a');
console.log('arr: ', arr);
console.log('copyArr: ', copyArr);
/*
arr: ["b", "c", "d", "a"]
copyArr:["b", "c", "d", "a"]
*/
💡3.なぜReactで不変性を保つのか
💡4.不変性を保ち、状態を変える
-アレイに追加
setUsers(state.array.concat(user));
-アレイから削除
const onRemove = id => {
// user.id 가 id 인 것을 제거
setUsers(users.filter(user => user.id !== id));
};
-アレイで変更
const onToggle = id => {
setUsers(
users.map(user =>
user.id === id ? { ...user, active: !user.active } : user
)
);
};
-オブジェクトから追加
setState(state => {...state, key: value})
-オブジェクトから削除
setState(state => {..._.omit(state, 'deleteKey')})
-オブジェクトでの変更
setState(state => {...state, key: newValue})
- immer
produce
関数を覚えるだけでいいです.パラメータをダブルクリックすると、割り当てられたオブジェクト(配列)の関数が変更されます.
import produce from "immer";
const baseState = [
{
todo: "javascript 공부",
done: true
},
{
todo: "Algorithm 공부",
done: false
}
];
const nextState = produce(baseState, draftState => {
draftState.push({ todo: "CS 공부" });
draftState[1].done = true;
});
-reduxからimmerに書き込む
const initialState = [{ name: "chichi", address: { city: "seoul" } }];
export default function auth(state = initialState, action) {
switch (action.type) {
case SET_INFO:
return {
...state,
name: "sh",
address: {
...state.address,
city: "busan"
}
};
default:
return state;
}
}
const initialState = [{ name: "chichi", address: { city: "seoul" } }];
export default function auth(state = initialState, action) {
produce(state, draft => {
switch (action.type) {
case SET_INFO:
draft[0].name = action.data.name;
draft[0].address.city = action.data.city;
break;
case ADD_INFO:
draft.push({ name: "sh", address: { city: "busan" } });
default:
return draft;
}
});
}
💡5.整理
Reference
この問題について([ReactJS] Immutability), 我々は、より多くの情報をここで見つけました https://velog.io/@cch5980/ReactJS-Immutabilityテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol