useState을 사용해서 배열값을 저장하려다가, 반복문에서는 적용이 되지 않길래 공식문서를 찾아봤다.
알고보니 react hook은 반복문 안에서 적용이 안 된다고 한다... 여태 모르고 삽질하고 있었던지라 한 번 정리해두고자 한다.
반복문, 조건문, 중첩 함수 내에서 hook 호출 불가
컴포넌트 렌더링 시, 여러 번 hook이 호출되더라도 올바른 상태로 유지될 수 있도록 한다.
이거 때문에 진짜 삽질을 오지게 하고, 굉장히 비효율적인 코드를 만들었다.
일단 이 코드는 카테고리 별로 노트 리스트를 받아오기 위함인데, 이때 flatlist로 노트를 띄워주기 위해 여러 과정을 거쳤다.
우선 아래와 같이 필요한 배열과 변수들을 선언해주었다.
const _title = [];
const _date = [];
const _noteId = [];
const [userId, setUserId] = useState('');
const [categoryName, setCategoryName] = useState('');
const [category, setCategory] = useState('');
const [notes, setNotes] = useState('');
const memos = [];
useState를 axios 코드 내의 반복문에 적용할 수 없기에, flatlist의 객체 배열을 만들어주기 위해 각각 원소 배열을 따로 변수 배열에 저장해 받아왔다.
react에서는 javascript의 push 대신 concat이나 map 또는 spread 연산자를 사용하기를 권장하던데.. 나는 concat이나 map을 쓰면 자꾸 오류가 나고, 그냥 push가 편해서 이걸 사용했다.
const setMemos = (i) => {
memos.push({
id: _noteId[i],
title: _title[i],
date: _date[i]
});
}
const getNotes = async () => {
try {
await axios.get(
`/notes/${userId}/all?category=${category}`
)
.then(function (response) {
if(response.data['success'] == true) {
// 반복문을 사용해서 각 메모 별로 title, date, note id를 저장해주었다.
for(let i = 0; i < response.data.result.length; i++){
_title.push(response.data.result[i]['title']);
_date.push(response.data.result[i]['date']);
_noteId.push(response.data.result[i]['note_id']);
// setMemos 함수에 객체 배열로 각각의 원소를 저장해주었다.
setMemos(i);
}
// 저장한 memos를 notes에 배열로 넣어주었다.
setNotes(memos);
}
})
.catch(function (error) {
console.log(error.response);
})
} catch (error) {
console.log(error);
}
};
// 앞서 작성한 Axios와 useEffect를 사용하기 위한 글 참고
useEffect(()=> {
setCategory(route.params.category);
setUserId(route.params.userId);
getNotes();
}, [userId, category]);
여기서 keywords는 data 안에 배열로 저장되기 때문에, 이 원소들을 다른 배열에 저장해 받아오는 게 필요했다. 주로 배열을 저장하는 데 사용하던 useState hook은 반복문 안에 사용이 불가능하기 때문에, keyword 배열을 따로 생성해서 push로 데이터를 받아왔다.
그 후, useState 배열에 concat을 활용해 넣어주었다.
for(let i = 0; i < response.data.result.keywords.length; i++){
_keyword.push(response.data.result.keywords[i]['keyword']);
}
setKeywords(keywords.concat(_keyword));
이거는 hashtag를 보여주어야 했기 때문에, 반복문을 돌려 hashtag를 보여주었다.
var hashtag = [];
for(let i = 0; i < 5; i++){
hashtag.push(
<Text style = {textStyles.hashtag}>#{keywords[i]}</Text>
)
}
(추가) 아 왜 map을 까먹고있었니^^
참고) Hook의 규칙