子反应组件始终落后一个更新

时间:2020-08-27 11:44:27

标签: reactjs react-hooks

我有一个父组件和一个子组件。

父级组件将新图像上传到API。子组件显示从相同API返回的图像列表。

我面临的问题是子组件始终落后一个更新。也就是说,将单个图像上传到父组件不会刷新它,但是更新第二个图像会刷新。添加第三个图像将显示前两个图像,但不显示第三个图像,依此类推。

父组件

function MediaLibrary(props) {
const [imageUploaded, setImageUploaded] = useState('');
const imagesGateway = ImagesGateway();

const handleUploadImage = async (event) => {
    event.preventDefault();

    let formdata = new FormData();
    formdata.append("image", event.target.files[0]);

    await imagesGateway.postArticleImages(props.articleId, formdata);

    // Update Files uploaded to try to trigger a refresh
    setImageUploaded(Math.random); 
}

return (
    <Container className="pt-4">
        <MediaList articleId={props.articleId} refresh={imageUploaded} />
        <Form.File
            id="articleImage"
            label="Upload Image"
            custom
            onChange={handleUploadImage}
        />
    </Container>
)

导出默认MediaLibrary;

子组件

function MediaList(props) {
    const [images, setImages] = useState([]);
    const [loading, setLoading] = useState(true);
    const imageGateway = ImageGateway();

    useEffect(() => {
        fetchImages();
    }, [props]);

    const fetchImages = async () => {
        setLoading(true);
        const articleImages = await imageGateway.getArticleImages(props.articleId);
        setImages(articleImages);
        setLoading(false);
    }

    return (
        <Container>
            <Row>
                {images.map(image => (
                    <Image src={image} thumbnail />
                ))}
            </Row>
        </Container>
    )
}

export default MediaList;

编辑:好像每次都使用来自API的正确数据命中子组件中的fetchimages函数,但这不会触发子组件显示新鲜数据。

2 个答案:

答案 0 :(得分:2)

您是否尝试过这样的方法:

父组件

import React, { useState } from "react";
import MediaList from "./MediaList";

export default function App() {
  const [loading, setLoading] = useState(false);
  const [images, setImages] = useState([]);
  const imagesGateway = ImagesGateway();

  const handleUploadImage = async (event) => {
    event.preventDefault();

    let formdata = new FormData();
    formdata.append("image", event.target.files[0]);

    await imagesGateway.postArticleImages(props.articleId, formdata);

    // Call fetchImages() everytime when you post something new
    fetchImages();
  };

  const fetchImages = async () => {
    setLoading(true);
    const articleImages = await imageGateway.getArticleImages(props.articleId);
    setImages(articleImages);
    setLoading(false);
  };

  return (
      <Container className="pt-4">
        <MediaList images={images} />
        
        <Form.File
          id="articleImage"
          label="Upload Image"
          custom
          onChange={handleUploadImage}
        />
      </Container>
  );
}

子组件

import React from "react";

function MediaList(props) {
  // Gettings images from props
  const { images } = props;

  return (
    <ul>
      {images.map((image) => (
        <li>
          {image.title}
          <img src={image} alt="img" />
        </li>
      ))}
    </ul>
  );
}

export default MediaList;

答案 1 :(得分:0)

如下更新您的子组件,以使您的组件受刷新道具更改的影响:

function MediaList({ articleId, refresh }) {
    const [images, setImages] = useState([]);
    const [loading, setLoading] = useState(true);
    const imageGateway = ImageGateway();

    useEffect(() => {
        fetchImages();
    }, [refresh]);

    const fetchImages = async () => {
        setLoading(true);
        const articleImages = await imageGateway.getArticleImages(articleId);
        setImages(articleImages);
        setLoading(false);
    }

    return (
        <Container>
            <Row>
                {images.map(image => (
                    <Image src={image} thumbnail />
                ))}
            </Row>
        </Container>
    )
}

export default MediaList;