사용자가 답변을 textarea
영역에 적으면 이 답변을 다른 페이지에 답변을 하고 수정하려고 돌아왔을 때도 유지된 상태로 보여줘야 했다. 또 사용자가 각 페이지마다 답변한 내용을 한꺼번에 데이터베이스에 저장하기 위해서는 전역 상태로 관리하는게 편하기 때문에 Recoil
을 이용해 사용자의 답변을 저장하기로 했다.
이전 페이지에서 사용자가 자신이 답변하고 싶은 키워드를 누르면, 그 키워드에 대한 답변을 작성한다.
위 페이지에서 선택했던 키워드도 전역 상태로 저장하고, 해당 페이지에 왔을
때는 사용자가 선택한 키워드에 대한 답을 쓸 수 있는 컴포넌트를 보여준다.
export const answerState = atom({
key: 'otherAnswerState',
default: {
name: '',
strength: [], // 사용자가 선택한 키워드 저장
strengthReview: { // 키워드 선택 이유 답변 저장
/*
keyword: review_description,
*/
},
},
});
strengthReview[키워드]
로 해당 키워드에 대한 답변을 불러올 수 있도록 객체 형태로 정의했다.
const [answer, setAnswer] = useRecoilState(answerState);
const clickChip = (chip) => {
let update = [...answer.strength]
if (update.includes(chip)) { // 칩 선택 취소
setAnswer({
...answer, strength: [...update.filter(item => item !== chip)]
})
} else if (update.includes(chip) === false) { // 칩 선택
if (answer.strength.length < 3) {
update.push(chip);
setAnswer({
...answer, strength: update
})
}
}
사용자가 키워드 칩을 누를 때마다 동작하는 함수이다. 해당 chip을 누르면 strength 배열에 이미 있는 경우에는 선택이 취소되지만, chip이 배열에 없는 경우에는 칩을 strength 배열에 추가한다. (3개까지만 선택 가능하므로 길이가 3 이하일 때만 배열에 추가하도록 했다.)
배열 추가 혹은 삭제 시에는 setAnswer
를 이용해준다. setAnswer({...answer, strength: update}) 이런 식으로 써주면 된다.
...answer
⇨ 이전에 전역 상태에 저장된 값을 불러와서 복사해준다.strength: update
⇨ 우리가 변경해줄 값은 answerState에서 strength 값이므로, strength 값을 변경 원하는 update 값으로 변경해준다.위와 같이 저장하면, 선택한 키워드가 strength 배열에 저장된다.
사용자가 선택한 키워드가 최대 3개까지인데, 각 키워드에 대한 답을 저장해두어야한다. 위에서 전역 상태를 정의할 때, 키워드는 strength
배열에 저장하기로 했고 선택한 키워드에 대한 답변은 strengthReview
에 저장하기로 했다.
strength
상태 관리: 배열 형태로 저장하고 삭제하는 업데이트 방법은 ❶번에서 설명했다.
객체 상태 저장하기
각 키워드에 대한 답은 키워드 이름: 해당 키워드에 대한 답으로 객체로 저장된다.
function AnswerBox(props) {
const [answer, setAnswer] = useRecoilState(answerState);
const chipTitle = "키워드1";
const [inputText, setInputText] = useState(answer.strengthReview[chipTitle] || "");
/* 사용자가 textarea에 입력할 때마다 값 업데이트 */
const handleChange = (e) => {
setInputText(e.target.value);
setAnswer({
...answer,
strengthReview: {
...answer.strengthReview,
[chipTitle]: e.target.value
},
});
};
return (
<>
<textarea
value={inputText}
placeholder="민지님과 OO 프로젝트를 진행할 때 oo아이디어에 관해 팀원의 의견을 수렴하는 과정에서 이야기를 경청하는 모습이 인상 깊었어요 :)"
onChange={handleChange}
/>
</>
)
}
① textarea
영역에 사용자가 글을 작성하게 되면 onChange에 정의된 함수인 handleChange가 동작한다.
② handleChange
에서는 사용자가 입력한 값을 inputText에 저장하고, 전역 상태에 strengthReview
에 사용자가 입력한 값을 업데이트 해준다.
strengthReview는 배열이 아닌 객체이므로 저장할 때 다음과 같이 저장해준다.
setAnswer({ ...answer, strengthReview: { ...answer.strengthReview, [chipTitle]: e.target.value }, });
chipTitle은 사용자가 선택한 키워드로 이 키워드에 대한 사용자 답변을 저장한다.
💡 [chipTitle]로 써준 이유
객체 안에서 변수 chipTitle을 쓰려면 대괄호를 사용해주어야 하기 때문이다.
선택한 키워드가 저장되어 다음 페이지에서 보여지고, 적은 답변도 페이지를 이동하고 돌아온 후에도 유지되는 것을 볼 수 있다.