seminar-2020
seminar-2020 copied to clipboard
예제로 올려주신 context-tutorial project에 관해
올려주신 코드를 실행했을 때, toggle이 정상 작동하지 않고(한번 켜지면 다시 안 꺼짐), add item을 했을 때 아이템이 최대 한 개만 추가되며, 아이템이 추가된 상태에서 toggle을 했을 때는 추가된 아이템이 사라집니다. 아마도 정상 작동하는 상태인 건 아닌 것 같은데, 의도하신 건지, 아니면 버그인 건지 궁금합니다!
레포 clone한 다음 yarn 하고 yarn start하는 방법으로 실행해 보았습니다! 브라우저는 구글 크롬 이용하였습니다.
앗 실수로 라벨을 안 달았네요..ㅠㅠ 아마 권한도 없는 것 같은데 수정을 어떻게 하는지 모르겠습니다(Frontend HW3)ㅠㅠ 죄송합니다
@woohm402 권한 초대 다시 드리겠습니다 :)
저도 원래 의도하신 작동은 add Item을 여러 번하면 item들이 계속 추가되고, toggle 버튼을 누르면 같은 name
을 가진 요소들이 배경색이 on/off 되는 방식이었다고 생각했습니다. (만약 아니거나 제가 놓친 부분 있다면 다시 정정 부탁드립니다!)
올려주신 코드가 위의 방식대로 작동하지 않는 이유는 setState()
안에서 state
가 비동기로 update되기 때문에 이전 state
를 제대로 반영하지 못해서인걸로 알고 있습니다. 그래서 다음 state
를 이전 state
로부터 직접적으로 계산하면 안 되고, function
을 전달받는(이전 state를 받아 다음 state를 반환하는 function) setState()
의 두 번째 form을 사용해야 하는 것 같습니다. 해당 내용이 설명되어 있는 React Doc 페이지입니다.
그래서 저의 경우에는 setState()
하는 부분의 코드를
const addItem = ({ name, seminar }) => {
setState({
...state,
list: [
...state.list,
{ name, seminar, on: false }
]
})
}
const onToggle = (name) => {
setState({
...state,
list: state.list.map(item => {
return item.name === name ?
{ ...item, on: !item.on } :
{ ...item }
})
}
)
}
setState((prevState) => {})
의 형식을 이용하여 아래와 같이 고쳤더니
const addItem = ({ name, seminar }) => {
setState((state) => ({
...state,
list: [...state.list, { name, seminar, on: false }],
}));
};
const onToggle = (name) => {
setState((state) => ({
...state,
list: state.list.map((item) => {
return item.name === name ? { ...item, on: !item.on } : { ...item };
}),
}));
};
잘 작동하더라고요. 저도 고민했던 부분이라 참고가 되셨으면 좋겠습니다! 혹시 제가 놓친 부분이나 잘못 이해한 부분 있다면 지적 부탁드립니다!
아하.. 비동기일 수 있어서 발생하는 문제였군요ㅠㅠ 저도 잘 작동하네요 감사합니다!!
약간 피곤한 상태에서 작성하다보니 실수가 있었습니다 ㅠㅠ @jusjinuk 께서 해결하는 법은 정확히 알려주셨네요 위 방법대로 수정하면 잘 작동합니다!
useState
를 이용해서 context
의 value
를 state
로 만들고 이를 관리합니다.
이 value
에는 전역으로 관리하는 배열 뿐만 아니라, 이에 변화를 줄 함수
또한 포함합니다.
예시 코드를 보시면 setState
는 배열
에만 액션을 가합니다. 따라서, 액션 함수
를 호출할 때마다 배열
은 값이 변하게 됩니다.
하지만, 두 개의 액션 함수
는 useState
로 state
를 선안한 시점부터 사이트가 꺼질 때까지 동일한 함수를 가지고 있습니다.
문제는 이 액션 함수
자체에 있습니다. 액션 함수
에는 아래와 같이 state
를 참조하는 부분이 있습니다.
setState({
...state,
list: state.list.map(() => {})
})
문제는 이 state
는 액션 함수
가 선언되는 시점을 기준으로 합니다.
따라서, 이 state
는 useState
에 인자로 전달된 값과 동일합니다.
이 함수를 아무리 호출한다 할지라도 초기값을 기준으로 배열이 변합니다.
따라서, 아무리 추가해도 하나만 추가되고, toggle도 하나만 작동합니다.
이를 해결하기 위한 방법은 위해서 정확하게 말씀해주셨는데요
setState((prev) => {})
와 같은 꼴로 setState
를 작성하시면 됩니다.
이 때 콜백 함수로 전달된 prev
에는 최신의 state
값이 자동으로 전해지고
이를 사용하시면 정상 작동할 겁니다.
@jusjinuk 께서 올려주신 링크는 Class Component
의 setState
에 대해서 얘기하고 있는 것 같아요.
지금 세미나에서 사용 중인 건 react hooks
의 useState
라 해당 링크와 약간의 차이는 있을 수 있습니다.
예를 들면, react hooks
의 setState
함수는 두 번째 파라미터를 전달받지 않습니다 ㅎㅎ
정확히는 그런 이유였군요 감사합니다!
아 그런 것이군요! 지난주에 이미 올라와 있었네요.... ㅎㅎ 감사합니다