Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.1k views
in Technique[技术] by (71.8m points)

javascript - Reversing an array stored in State doesnt force re-render of component in React

This is part of a larger component but I've summarised it in a reproducible example below:

? ? import React, {useState} from 'react'

? ?
? ? function App() {
? ? ? ? const [data,setData] = useState([{name:'first'},{name:'second'},{name:'three'}])

? ? ? ?// Function to reverse a given array
? ? ? ? const reverseArray = (array) => {
? ? ? ? ? var reverseArray = array.reverse();
? ? ? ? ? return reverseArray;
? ? ? ? }


? ? ? ? return (
? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? {data.map((item,index)=>{
? ? ? ? ? ? ? ? ? ? ? ? ?return <h1 key={index}>{item.name} index: {index}</h1>
? ? ? ? ? ? ? ? ? ? })}
? ? ? ? ? ??

? ? ? ? ? ? ? ?     {/*When I click this I expect the div above to rerender */}
? ? ? ? ? ? ? ? ? ? <button onClick={()=>{
? ? ? ? ? ? ? ? ? ? ? ? var newData = data;
? ? ? ? ? ? ? ? ? ? ? ? setData(reverseArray(newData))}
? ? ? ? ? ? ? ? ? ? }>
? ? ? ? ? ? ? ? ? ? ? Reverse Order
? ? ? ? ? ? ? ? ? ? ?</button>

                    {/* Logs state to the console to check order is reversed */}
? ? ? ? ? ? ? ? ? ? <button onClick={()=>console.log(data)}>Log Data</button>

                    {/* Clearing the state by setting to empty array */}
                    <button onClick={()=>setData([ ])}>Clear Data</button>

? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? </div>
? ? ? ? )
? ? }

So my main issue, is that the mapped data doesn't seem to change with a state update. As a check that state does update, I have a clear button which does clear the data state and the list goes blank.?

When I click the reverse button, I expect the data to be reversed (i.e. "first" to be last and "three" to be in first place). I'm sure my state is updated as I can check it with console logs before and after the reverse button is clicked.

My thought process was to create a completely new reversed array (newData) and set this as the state. However, the mapping doesn't reflect this order change. What am I missing here??

I understand components in React will rerender when state changes, why does setting a new array to state not trigger this? But the rerender is apparent when clearing the state?

My sandbox for this: https://codesandbox.io/s/immutable-sun-oujqj?file=/src/App.js


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Demo: https://codesandbox.io/s/array-reverse-react-state-0v67h

Array.prototype.reverse() reverses the elements in place. You'll need to pass a new array into setData().

<button
  onClick={() => {
    var newData = data;

    // Create a new array using the spread operator
    setData(reverseArray([...newData])); 
  }}
>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...