I have 2 components. One is App
component and other one is NumbersList
component.
The NumbersList
is a child component of the App
component.
The App
component receives a list of numbers called lst as a prop.
The App
component has 2 buttons sort Ascending and sort Descending and they try to do what the name implies.
The app component:
import React, { useState } from 'react';
import './style.css';
import NumbersList from './NumbersList';
export default function App({ lst }) {
const [sortedLst, setSortedLst] = useState(lst);
function sortAscHandler() {
setSortedLst((prev) => prev.sort((a, b) => a - b));
}
function sortDescHandler() {
setSortedLst((prev) => prev.sort((a, b) => b - a));
}
return (
<div>
<button onClick={sortAscHandler}>Sort Ascending</button>
<button onClick={sortDescHandler}>Sort Descending</button>
<NumbersList lst={sortedLst} />
</div>
);
}
The NumbersList component:
import React from 'react';
const NumbersList = ({ lst }) => {
return (
<ul>
{lst.map((num) => (
<li>{num}</li>
))}
</ul>
);
};
export default NumbersList;
The main index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
const lst = [4, 3, 2, 1, 7, 6, 5, 100, 9, 8];
ReactDOM.render(<App lst={lst} />, document.getElementById('root'));
The problem is the the when the buttons are clicked, the sortedLst is not updated in the view.
stackblitz-link: https://stackblitz.com/edit/react-jyqeuy?file=src/index.js
Thank you in advance
CodePudding user response:
Array.prototype.sort
is an in-place sort. In other words, it mutates the array it operates on and doesn't return a new array reference.
The
sort()
method sorts the elements of an array in place and returns the sorted array.
Make a shallow copy first, then sort the new array reference.
export default function App({ lst }) {
const [sortedLst, setSortedLst] = useState(lst);
function sortAscHandler() {
setSortedLst((prev) => prev.slice().sort((a, b) => a - b));
}
function sortDescHandler() {
setSortedLst((prev) => prev.slice().sort((a, b) => b - a));
}
return (
<div>
<button onClick={sortAscHandler}>Sort Ascending</button>
<button onClick={sortDescHandler}>Sort Descending</button>
<NumbersList lst={sortedLst} />
</div>
);
}