简体   繁体   English

在 React 中使用 setTimeout 强制更新 state

[英]Using setTimeout to force state update in React

I'm building a React App and having issues with re-renders when state is updated.我正在构建一个 React 应用程序,但在更新 state 时遇到重新渲染问题。 Basicly I just manipulate a bunch of arrays and need things to re-render inside the aplication.基本上我只是操纵一堆 arrays 并需要在应用程序内部重新渲染。

So I tried to put a setTimeout before the change of state and "Voilà," it worked, now I have a lot of setTimeouts updating states and I know this is not the best way to do it, so my question is: how can I do this without using the timeouts?所以我试着在 state 和“Voilà”的变化之前放置一个setTimeout ,它起作用了,现在我有很多setTimeouts更新状态,我知道这不是最好的方法,所以我的问题是:我怎么能在不使用超时的情况下执行此操作?

The example below is a function when on click update a value in a object inside an array:下面的示例是一个 function,当点击更新一个数组中的 object 中的值时:

const documentCopy = selectedDocument;
documentCopy.pages.find((page) =>
  page.id === id
    ? page.active === true
      ? (page.active = false)
      : (page.active = true)
    : null,
);
setTimeout(() => {
  setSelectedDocument(null);
  setSelectedDocument(documentCopy);
}, 1);

And this is the rendering implementation:这是渲染实现:

{selectedDocument && selectedDocument.pages.map((page, i) => (
        <IconButton
            key={page.id}
            onClick={() => handleCheckImage(page.id)}
        >
            <img src={page.img}
                width='85'
                height='120'
                alt={'document'}
            />
            <Checkbox className={
                page.active
                    ? classes.imageBox
                    : classes.imageBoxHidden
                }
                checked={page.active}
                name={page.id}
                color='primary'
            />
        </IconButton>
    )
)}

Basically I just need to click on an image and when I click on the checkbox for that particular image it gets checked or unchecked and displayed on the screen.基本上我只需要点击一张图片,当我点击该特定图片的复选框时,它会被选中或取消选中并显示在屏幕上。

Sorry for my, not great, english and any tips are welcome.对不起,我的英语不是很好,欢迎任何提示。

Ty all in advance.提前告诉你。

When react decideds to do a rerender because of a state change it looks at the previous state and the new state. It then decides if these are different and rerenders the component.当 React 由于 state 更改而决定重新渲染时,它会查看之前的 state 和新的 state。然后确定它们是否不同并重新渲染组件。 If the previous and new state are not different it doesnt rerender.如果之前的和新的 state 没有不同,它就不会重新渲染。 This works for primitive types because when they are saved a new section in memory is assigned to the value.这适用于原始类型,因为当它们被保存时, memory 中的一个新部分被分配给该值。

However it doesnt work as expected when comparing Arrays. This has to do with the way that Arrays are stored in memory. They are stored by reference instead of creating a new value in memory. This is shown in the code below, you would expect the console.log to print false, but it actually prints true.然而,当比较 Arrays 时,它没有按预期工作。这与 Arrays 存储在 memory 中的方式有关。它们通过引用存储,而不是在 memory 中创建新值。这在下面的代码中显示,您会期望console.log打印 false,但它实际上打印 true。 This is because arr1 and arr2 are actually the same array because they point to the same value in memory.这是因为arr1arr2其实是同一个数组,因为它们指向memory中的同一个值。

 const arr1 = ['dog', 'cat', 'bird']; const arr2 = arr1; arr2.push('fish'); console.log(arr1 === arr2);

As for react a way to get around this is you can create a new array when you set it in state. So in your case you could do something like this to get a rerender.至于解决这个问题的一种方法是,当你在 state 中设置它时,你可以创建一个新数组。所以在你的情况下你可以做这样的事情来重新渲染。 The code creates a brand new array / value in memory containing your original arrays data.该代码在 memory 中创建了一个全新的数组/值,其中包含您的原始 arrays 数据。

 setSelectedDocument([...documentCopy]);

The reason the timeout is working is because you are setting the value of the state to null and then to the page.超时工作的原因是因为您将 state 的值设置为 null,然后再到页面。 So React sees these two as different.所以 React 认为这两者是不同的。

Hope this helps, further reading if you are interested: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0希望这会有所帮助,如果您有兴趣,请进一步阅读: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM