프내기
[map / useState]파베에서 데이터 받아왔는데 배열에 업데이트가 안된다 본문
파베에서 데이터 받아와서 클라이언트 측에 저장할라했더니 안됩니다
const [posts, setPosts] = useState<any>([]);
useEffect(() => {
async function getData() {
const db = getFirestore(firebasedb);
const querySnapshot = await getDocs(collection(db, "posts"));
querySnapshot.docs.map((doc) => {
setPosts([...posts, doc.data()])
});
}
getData();
}, []);
파이어스토어에서 불러온 데이터 배열을 map을 돌려서 posts 배열에 업데이트 시키고 싶었다
querySnapshot.docs.map((doc) => {
console.log(doc.data()) // 데이터가 하나하나 잘 들어온다
setPosts([...posts, doc.data()]) // map 한 번 돌때 마다 이전 데이터를 그대로 받아오고 새로운 데이터를 넣어준다
});
이랬더니 useEffect 밖에서 찍어준 posts의 결과가 이상했다.
각기 다른 데이터가 2개가 있다 치면, 첫 번째 데이터가 2개 들어와있는 배열이 있거나.
데이터가 하나만 들어온 배열이 찍히는 것이다.
결과가 매번 다른 것도 이상하다.

map안에서 돌때마다 setPosts로 업데이트 해주기
vs
map리턴값 받아서 변수에 할당 후 해당 변수를 setPosts에 업데이트
의 차이인데 왜 실패코드는 하나의 데이터만 담은 posts를 주는걸까??????
바로 함수형 setState와 map을 제대로 알지 못했기 때문이었다.
setPosts에 새로운 객체를 전달했을 땐 비동기작업이 여러번 일어나면 예상치 못한 동작이 일어날 수 있다. 개판됨.
그러니 함수형 setPosts를 함수형으로 작성하면 이전 상태값 받아서 새로운 상태 반환하니까 비동기 작업이 이전 상태 기준으로 이뤄지기에 원하는대로 업데이트를 보장해준다.
map은 배열을 반환한다. 그니까 이걸 변수에 담아서 setPosts에 새로운 객체로 담아주면 되는거였다.
useEffect(() => {
async function getData() {
const db = getFirestore(firebasedb);
const querySnapshot = await getDocs(collection(db, "posts"));
// data에 map의 리턴값을 담는다
const data = querySnapshot.docs.map((doc) => ({
...doc.data(), id: doc.id
}));
// data 객체를 setPosts의 인자로 담는다
setPosts(data);
}
getData();
}, []);
해결.
추가 질문))))
이것도 되는디?
useEffect(() => {
async function getData() {
const db = getFirestore(firebasedb);
const querySnapshot = await getDocs(collection(db, "posts"));
querySnapshot.docs.map((doc) => {
setPosts((prevValue: any) => [...prevValue, doc.data()])
});
}
getData();
}, []);
map의 리턴값을 변수에 담지않고 그냥 안에서 함수형 setState를 써서 작성한 코드도 되긴한다!
하지만 map의 사용목적에 맞지 않다.
이런 경우엔 forEach를 쓰는 것이 메소드의 제대로된 사용법이다.
바보같은 자문이었지만 메소드 개발하신 분도 이거보면 뿌듯해할듯.
끝
'Trouble Shooting' 카테고리의 다른 글
[yesorno 프젝]input에 같은 파일 재업로드하기(by onChange) (1) | 2023.12.20 |
---|---|
[typescript] ~ is possibly 'undefiend' (0) | 2023.12.08 |
[Promise]Property 'then' does not exist on type 'void' (0) | 2023.11.29 |
[Firebase]이미지object 를 File 형식으로 변환하기 (1) | 2023.11.29 |
[Styled-component] Styled component에 props 넘기기(with TS) (2) | 2023.11.24 |