Math.random
과 Math.floor
를 사용하여 Randomkimchi를 콘솔로 찍어보면 랜덤의 4개의 데이터가 잘들어온다.export default function RecommendProduct() {
const [recommendedProduct, setRecommendedProduct] = useState([]);
const fetchproduct = async () => {
const { data } = await axios.get(`http://localhost:3001/kimchis`);
// 1. 데이터를 불러온다. : data
// 2. 랜덤 함수를 사용해서 숫자를 받는다. : number
// 3. data[number]를 인덱스로 사용한다.
// 4. 변수에 push하여 data[number]해서 뿌려준다.
const Randomkimchi = [];
for (let i = 0; i < 4; i++) {
let randomNum = Math.floor(Math.random() * data.length);
Randomkimchi.push(data[randomNum]);
}
};
useEffect(() => {
fetchproduct();
}, []);
리액트에서는 배열이나 객체 데이터 등 참조 자료형 데이터의 변동을 리액트가 원활하게 감지하여 정상 작동하도록 한다.
push
참조 자료형의 가변 내장 함수를 사용하면 내부의 데이터는 변하더라도 그 주소값은 그대로 이다. 이것은데이터 무결성 제약 조건 위배
에 해당하여 문제를 발생시킬 여지를 남긴다.무결성을 유지하려면 기존 데이터를 수정하는 가변 내장 함수(push, unshift, pop, splice)를 사용하면 안된다.
새로운 데이터를 반환해주는 함수인 무결성 내장 함수(map, slice, filter)를 사용해야 된다.
새로운 값을 기존 값에 push를 해주고 리액트가 변화를 감지할 수 있도록 새로운 배열을 만들어 state가 변경
되었음을 인지하도록 해주었다.
// 상품 추천 랜덤 함수
const Randomkimchi = [];
let allKimchis = data;
for (let i = 0; i < 4; i++) {
let randomNum = Math.floor(Math.random() * allKimchis.length);
Randomkimchi.push(allKimchis[randomNum]);
//console.log(Randomkimchi); -->4개의 데이터가 잘들어온다.
allKimchis.splice(randomNum, 1);
// console.log(allKimchis); --> for문을 돌면서 추천 상품에 같은 아이템 추천이 나오지 않도록 randomNum 즉 인덱스값의 1개씩을 splice해준다.
}
setRecommendedProduct(Randomkimchi); // setRecommendedProduct에 Randomkimchi의 값을 새로운 배열에 업데이트를 해준다.
// console.log(allKimchis);
};
아래 블로그에 자세히 나와있다!
참조 타입과 setState - 배열/객체 상태관리 완벽 정리