search

Home  >  Q&A  >  body text

Using useEffect and reactStrictMode: Optimizing React components for performance and reliability

<p>I have a challenge, I want to load a part of the array into a new array called "loadedData" and only display the loaded data because the component is very heavy. </p> <p>However, on first load, I ran into a lot of problems because useEffect seemed to mess it up. The first load happens twice, and the first data is pushed into the array once for each render. If I remove "reactStrictMode" it works as expected, but I don't want to "cheat" without understanding the consequences. Someone who understands the problem better than me put it there for a reason.. </p> <p>The isLoading state cannot prevent a second run during the initial load - this is a suggestion I've received in other threads related to this issue. </p> <p>Does anyone know why the first useEffect ignores the isLoading state and how to deal with it? </p> <pre class="brush:php;toolbar:false;">// Try to load the visible part, but don't load more const [loadedData, setLoadedData] = useState([]); const [isLoading, setIsLoading] = useState(false); const addMoreData = async () => { if (loadedData.length >= data.length) return; const startIndex = loadedData.length; const preferredLoadLength = 1; const endIndex = startIndex preferredLoadLength; const newData = data.slice(startIndex, endIndex); setLoadedData((prev) => [...prev, ...newData]); }; // Check if the table has been scrolled to the bottom after mounting and fetching data and immediately needs to fetch more data useEffect(() => { const { scrollHeight, scrollTop, clientHeight } = tableContainerRef.current; if ( scrollHeight == clientHeight && scrollTop == 0 && loadedData.length < data.length ) { const addNewDataFunction = async () => { if (isLoading) { return; } setIsLoading(true); await addMoreData(); setIsLoading(false); }; addNewDataFunction(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [data.length, loadedData.length, isLoading]);</pre> <p><br /></p>
P粉739706089P粉739706089465 days ago584

reply all(1)I'll reply

  • P粉183077097

    P粉1830770972023-08-19 11:59:00

    You can simply change this line in the addMoreData function

    setLoadedData((prev) => [...prev, ...newData]);
    

    for

    setLoadedData([...loadedData, ...newData]);
    

    This will cause the state to be updated based on the value when it is currently rendered, because the second useEffect run time the component has not yet re-rendered, so the changes made by the first component have not yet been reflected, so loadedData has not been updated yet.

    When you use the functional form to update, prev is the real-time value of the state. It is normal for you to encounter this situation when using strict mode in development.

    Finally, get rid of isLoading, it won't help fix the problem.

    Note: When strict mode is enabled, it is more recommended to use the setState function form, but it is not recommended in useEffect because this hook will run when the component is mounted. twice.
    Additionally, when you include data.length and loadedData.length in the dependency array, this will cause useEffect when any of those values ​​change will be triggered.

    reply
    0
  • Cancelreply