현재 스프레드 연산자를 사용하여 React에서 항목을 배열로 푸시하려고 하는데 다음 오류가 발생합니다.
PlacesForm.jsx 내의 PhotoUploader 구성 요소에서 오류가 발생합니다. 아래 구성요소에 코드를 포함시켰습니다.
PlacesForm.jsx:
으아아아addPhotobyLink() 및 uploadPhoto() 함수에서 오류가 발생합니다. 게시물 요청과 백엔드가 제대로 작동하고 둘 다에 대해 "filename"이 정의되어 있지만 "setAddedPhotos" 부분에 문제가 있습니다. 구성 요소 자체는 다음과 같습니다(PhotoUploader.jsx):
으아아아지금까지 시도한 사항은 다음과 같습니다.
import axios from 'axios' import React, { useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' import AccountNav from './AccountNav' import Perks from './Perks' import PhotosUploader from './PhotosUploader' function PlacesForm() { const {id} = useParams() const [title, setTitle] = useState("") const [address, setAddress] = useState("") const [addedPhotos, setAddedPhotos] = useState([]) //state in question const [description, setDescription] = useState("") const [perks, setPerks] = useState([]) const [extraInfo, setExtraInfo] = useState("") const [checkIn, setCheckIn] = useState("") const [checkOut, setCheckOut] = useState("") const [maxGuests, setMaxGuests] = useState(1) useEffect(() => { if (!id) return const getPlace = async () => { try { const {data} = await axios.get(`/places/${id}`) setTitle(data.title) setAddress(data.address) setAddedPhotos(data.addedPhotos) setDescription(data.description) setPerks(data.perks) setExtraInfo(data.extraInfo) setCheckIn(data.checkIn) setCheckOut(data.checkOut) setMaxGuests(data.maxGuests) } catch (e) { console.log(e) } } getPlace() }, [id]) const navigate = useNavigate() const inputHeader = (text) => { return ( <h2 className='text-2xl mt-4'>{text}</h2> ) } const inputDescription = (text) => { return ( <p className="text-gray-500 text-sm">{text}</p> ) } const preInput = (header, description) => { return ( <> {inputHeader(header)} {inputDescription(description)} </> ) } const handleSubmit = async (e) => { e.preventDefault() const placeData = { title, address, addedPhotos, description, perks, extraInfo, checkIn, checkOut, maxGuests } if (id) { //update try { const res = await axios.put('/places', { id, ...placeData, }) navigate('/account/places') } catch (error) { console.log(error) } } else { //create new place try { const res = await axios.post('/places', placeData) navigate('/account/places') } catch (error) { console.log(error) } } } return ( <> <div> <AccountNav /> <form onSubmit={handleSubmit}> {preInput('Title', 'Something catchy and memorable')} <input type="text" placeholder="title" value={title} onChange={e => setTitle(e.target.value)} /> {preInput('Address', 'be specific')} <input type="text" placeholder="address" value={address} onChange={e => setAddress(e.target.value)} /> {preInput('Photos', 'Best to have at least 4')} <PhotosUploader addedPhotos={addedPhotos} setAddedPhotos={setAddedPhotos} />
React에서는 일반적으로 상태 업데이트 기능을 전달하는 것을 권장하지 않습니다
이 작업을 수행하는 한 가지 이유는 불필요한 다시 렌더링을 발생시키고 코드를 추론하기 어렵게 만들기 때문입니다. 하위 구성 요소가 setAddedPhotos 함수를 prop으로 수신하고 이를 호출하면 상위 구성 요소의 상태 업데이트가 트리거되고, 이는 차례로 상위 구성 요소와 모든 하위 구성 요소의 다시 렌더링을 트리거합니다. 이는 구성 요소 트리가 크거나 상태가 자주 변경되는 경우 문제가 될 수 있습니다. 불필요한 재렌더링이 많이 발생할 수 있기 때문입니다.
또 다른 이유는 React를 사용하는 주요 이점 중 하나인 캡슐화 원칙을 위반할 수 있다는 것입니다. 캡슐화는 각 구성 요소가 고유한 독립적인 상태와 동작을 가져야 하며 상위 또는 형제 구성 요소의 상태를 직접 수정해서는 안 된다는 것을 의미합니다. 하위 구성 요소가 상태 업데이트 기능을 prop으로 받으면 상위 구성 요소의 상태에 액세스하고 수정할 수 있으므로 구성 요소 트리의 동작을 추론하기가 더 어려워질 수 있습니다.
setAddedPhotos 함수를 하위 구성 요소에 전달하는 대신. 이와 같이 동작 함수를 전달할 수 있습니다.
으아악