React报错:在添加到状态中时,项目不可迭代
P粉709644700
P粉709644700 2024-03-27 17:49:53
[React讨论组]

我目前正在尝试使用展开运算符将项目推送到 React 中的数组中,但是收到以下错误。

该错误发生在 PlacesForm.jsx 内的 PhotoUploader 组件中。我已将代码包含到下面的组件中。

PlacesForm.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 (
            

{text}

) } const inputDescription = (text) => { return (

{text}

) } 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 ( <>
{preInput('Title', 'Something catchy and memorable')} setTitle(e.target.value)} /> {preInput('Address', 'be specific')} setAddress(e.target.value)} /> {preInput('Photos', 'Best to have at least 4')}

该错误发生在 addPhotobyLink() 和 uploadPhoto() 函数中。发布请求和后端工作正常,并且为两者定义了“文件名”,但是“setAddedPhotos”部分出现了问题。这是组件本身 (PhotoUploader.jsx):

import axios from 'axios'
import React, { useState } from 'react'

function PhotosUploader({addedPhotos, setAddedPhotos}) {
    const [photoLink, setPhotoLink] = useState("")
    

    const addPhotoByLink = async (e) => {
        e.preventDefault()
        try {
            const {data:filename} = await axios.post('/upload-by-link', {link: photoLink})
            setAddedPhotos(prev => [...prev, filename])

        } catch (error) {
            console.log(error)
        }
        setPhotoLink("")
    }

    const uploadPhoto = async (e) => {
        const files = e.target.files
        const data = new FormData()
        for (let i = 0; i < files.length; i++) {
            data.append('photos', files[i])
        }
        try {
            const {data:filenames} = await axios.post('/upload', data, {
                headers: {'Content-type': 'multipart/form-data'}
            })
            setAddedPhotos(prev => [...prev, ...filenames])
        } catch (error) {
            console.log(error)
        }
    }

  return (
    <>
        
setPhotoLink(e.target.value)} type="text" placeholder="Add using link ....jpg" />
{addedPhotos?.length > 0 && addedPhotos.map((link) => (
))}
) } export default PhotosUploader

到目前为止,我已经尝试过:

setAddedPhotos(prev => [...prev, filename]) //didn't work
setAddedPhotos([...prev, filename]) //didn't work
setAddedPhotos([...addedPhotos, filename]) //didn't work, addPhotos isn't iterable error
setAddedPhotos(prev => [...addedPhotos, filename]) //didn't work

P粉709644700
P粉709644700

全部回复(1)
P粉293550575

在React中,一般不建议传递状态更新函数

这样做的一个原因是它可能导致不必要的重新渲染并使代码更难以推理。如果子组件接收 setAddedPhotos 函数作为 prop 并调用它,它将触发父组件中的状态更新,进而触发父组件及其所有子组件的重新渲染。如果组件树很大和/或状态频繁更改,这可能会成为问题,因为它可能导致大量不必要的重新渲染。

另一个原因是它可能违反封装原则,而封装原则是使用 React 的主要好处之一。封装意味着每个组件应该有自己独立的状态和行为,并且不应该直接修改其父组件或兄弟组件的状态。当子组件接收状态更新器函数作为 prop 时,它可以访问并修改其父组件的状态,这可能会使推理组件树的行为变得更加困难。

而不是将 setAddedPhotos 函数传递给子组件。你可以像这样传递行为函数。

import React from 'react';

function PlacesForm() {
  const [addedPhotos, setAddedPhotos] = useState([]);

  const handleAddedPhotos = (newStates) => {
    setAddedPhotos(prev => [...prev, ...newStates]);
  };

  return (
    
  );
}

function PhotosUploader({ addedPhotos, handleAddedPhotos }) {
    const uploadPhoto = async (e) => {
        const files = e.target.files
        const data = new FormData()
        for (let i = 0; i >
  );
}
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号