React - 警告:在 React 中渲染不同组件时无法更新组件

问题描述 投票:0回答:2

我在react项目中遇到了以下警告。

警告:渲染不同组件时无法更新组件 (

App
) 组件 (
TattooForm
)。

这是我的 TattooForm 道具工作流程的简要概述。

  • 我有一个父组件 App,它通过 props 将状态传递给子组件 TattooForm。
  • TattooForm 组件具有图像上传功能,用户可以选择身体部位并上传图像。我更新了父组件(App)中的状态,以将其再次传递给另一个子组件。

父App.jsx

function App() {
    const [uploadedImages, setUploadedImages] = useState({});

    const handleUploadedImages = (newImages) => {
        setUploadedImages(newImages);
    };

    return (
        <div>
            <TattooForm handleUploadedImages={handleUploadedImages} />
            <Experience uploadedImages={uploadedImages}/>
        </div>
    );
}

儿童纹身.jsx

const TattooForm = ({ handleUploadedImages }) => {
    const [selectedBodyPart, setSelectedBodyPart] = useState("");

    const handleImageChange = (e) => {
        const file = e.target.files[0];
        if (file) {
            const imageUrl = URL.createObjectURL(file);
            setSelectedBodyPart(imageUrl); // Local state update

            // Here I am calling the parent function to update the parent state
            handleUploadedImages({ [selectedBodyPart]: imageUrl });
        }
    };

    return (
        <div>
            <input type="file" onChange={handleImageChange} />
        </div>
    );
};
reactjs react-hooks react-state
2个回答
1
投票
const TattooForm = ({ handleUploadedImages, imageUrl }) => {
    const [pendingImages, setPendingImages] = useState(null);

    useEffect(() => {
        if (pendingImages) {
           handleUploadedImages(pendingImages); // I Passed updates to parent after render
         }
     }, [pendingImages, handleUploadedImages]);

    const onTattooUpload = (event) => {
        if (!selectedBodyPart) {
            alert("Please select a body part first.");
            return;
         }
        const file = event.target.files[0];
        if (file) {
            const tempImageUrl = URL.createObjectURL(file);

        // Update the state and call the parent handler inside an event handler
               setUploadedImages((prevImages) => {
                   const newImages = { ...prevImages, [selectedBodyPart]: 
                         tempImageUrl };
                   setPendingImages(newImages); // Store pending updates to be passed to parent later
                   return newImages;
               });
        } return;
    };

    return (
        <div>
            <input type="file" onChange={handleImageChange} />
        </div>
    );
};

0
投票

您在 TattooForm 中同步请求状态更新:

setSelectedBodyPart(imageUrl); // Local state update

并立即请求其父级中的状态更新:

// Here I am calling the parent function to update the parent state
handleUploadedImages({ [selectedBodyPart]: imageUrl });

所以你确实试图同时更新两个组件,而一个组件包含另一个组件。 我认为在这种情况下,React 无法“知道”如何协调这两个更新,这可能就是您收到此警告的原因。

我建议你只调用父级更新,让父级计算 imageUrl,然后使用 props 将其转发给子级:

父App.jsx

function App() {
    const [imageUrl, setImageUrl] = useState('');
    
    const handleUploadedImages = (file) => {
        const imageUrlFromFile = URL.createObjectURL(file);
        setImageUrl(imageUrlFromFile);

    };

    return (
        <div>
            <TattooForm handleUploadedImages={handleUploadedImages} imageUrl={imageUrl} />
            <Experience uploadedImages={imageUrl}/>
        </div>
    );
}

儿童纹身.jsx

const TattooForm = ({ handleUploadedImages, imageUrl }) => {


    const handleImageChange = (e) => {
        const file = e.target.files[0];
        if (file) {

            // Here I am calling the parent function to update the parent state
            handleUploadedImages(file);
        }
    };

    return (
        <div>
            <input type="file" onChange={handleImageChange} />
        </div>
    );
};

TattooForm 肯定不需要状态,这是行不通的:

setSelectedBodyPart(imageUrl); // Local state update
// selectedBodyPart not  yet updated
handleUploadedImages({ [selectedBodyPart]: imageUrl });

如果它有效,则相当于:

handleUploadedImages({ [imageUrl ]: imageUrl });

这没有任何意义。

© www.soinside.com 2019 - 2024. All rights reserved.