【问题标题】:useState not causing rerender when objects array changes *hooks*当对象数组更改 *hooks* 时,useState 不会导致重新渲染
【发布时间】:2021-07-15 21:16:41
【问题描述】:

我有一个对象,它有许多键,每个键都有一个对象数组。每个对象都包含一个图像文件,我需要显示该文件以预览用户刚刚上传的图像。但它显示的是上次上传的图片(不是刚刚上传的图片)

显然 useState 不会立即导致重新渲染,除非它看到数组或对象发生变化How do I update states onchange in an array of object in React Hooks

我按照上述(以及 StackOverflow 的一些类似建议)并在键处制作了对象的副本和数组的副本,但它仍然不起作用

知道为什么吗?

const Form = props => {
let [images, setImages] = useState({
    bannerPicture: [],
    projectPictures: [],
    projectsPictures: [],
    thumbnailPictures: []
})
const showTempImage = (file, tempFileObj, key) => {
    const imagesCopy = {...images}
    // add this image to the end of the array at the given key
    imagesCopy[key] = [...imagesCopy[key], tempFileObj]
    setImages({...imagesCopy})
....

}

我只希望图像在用户上传后立即显示

【问题讨论】:

  • 您检查过密钥是否正确吗?
  • @FireFighter 键绝对正确,是的
  • 我说得对吗?唯一阻止你进步的就是即使你的状态更新了也不重新渲染 UI?或者你的状态在 showTempImage 之后没有更新?
  • @SabitRakhim 好问题。所以我在 setImages 之后 console.log(images),它没有显示图像的变化,也没有重新呈现 UI。但是如果我上传另一张图片,它会在 UI 和图片状态中显示之前上传的图片
  • 你需要使用useEffect钩子和images作为依赖,并在useEffect body中上传图片后执行操作。

标签: reactjs react-hooks


【解决方案1】:

通过您的 async 函数执行此操作。

我假设您只会在上传完成后显示图片。

const mockUploadApi = () => {
  return new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve("uploadedImage");
    },1000);
  });
};


const App = () => {

  const [state,setState] = React.useState({
    status: "IDLE",
    image: ""
  });
  
  const uploadImage = () => {
    setState((prevState) => ({
      ...prevState,
      status: "UPLOADING"
    }));

    // THIS SHOULD USE await BUT THE SNIPPET DOES NOT ALLOW IT
    // SO I'M USING .then()
    
    mockUploadApi().then((uploadedImage) => {
      setState({
        status: "IDLE",
        image: uploadedImage
      });
    });
  };

  return(
    <div>
      <div>
        status: {state.status}
      </div>
      <div>
        image: {state.image || "no image"}
      </div>
      <div>
        <button onClick={uploadImage}>
          Upload
        </button>
      </div>
    </div>
  );
};

ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    相关资源
    最近更新 更多