I have my object perfectly updated but it does not render on screen (filteredData / handleOrder function). I tried using callback but also do not render.
Does anyone know what is the possible solution to render the object on the screen (filteredData)?
Here is the code which the object is updated:
setFilteredData(filteredData.sort((a, b) => (
(sort === 'ASC')
? a[column].localeCompare(b[column])
: b[column].localeCompare(a[column])
)));
Full code:
import React, { useContext, useState } from 'react';
import { Button, Form } from 'react-bootstrap';
import MyContext from '../../context/MyContext';
import './style.css';
function FilterByNumericValues() {
const {
filteredData,
order,
functions: { setFilteredData, setOrder },
} = useContext(MyContext);
function handleOrder(event) {
event.preventDefault();
const { column, sort } = order;
setFilteredData(filteredData.sort((a, b) => (
(sort === 'ASC')
? a[column].localeCompare(b[column])
: b[column].localeCompare(a[column])
)));
console.log(filteredData, 'filtered');
}
return (
<Form>
<Form.Group className="mb-3" controlId="order">
<Form.Check
data-testid="column-sort-input-asc"
type="radio"
label="Ascendent"
name="orderOption"
value="ASC"
onChange={ () => setOrder({ ...order, sort: 'ASC' }) }
/>
<Form.Check
data-testid="column-sort-input-desc"
type="radio"
label="Descendent"
name="orderOption"
value="DESC"
onChange={ () => setOrder({ ...order, sort: 'DESC' }) }
/>
<Form.Label>Order By</Form.Label>
<Form.Select
data-testid="column-sort"
name="orderFilter"
onChange={ ({ target }) => setOrder({ ...order, column: target.value }) }
value={ order.column }
>
{[...columnsIn, ...columnsOut].map(({ name }, index) => (
<option key={ index } value={ name }>{ name }</option>
))}
</Form.Select>
<Button
className="filter__order"
data-testid="column-sort-button"
onClick={ (event) => handleOrder(event) }
type="submit"
variant="warning"
>
Sort
</Button>
</Form.Group>
</Form>
);
}
export default FilterByNumericValues;
Arrays are reference values, sort() won't change the reference (doesn't create a new array), so React bails out the state update (search the Docs about "bailing out of state update").
You should pass a sorted copy of your original array to setFilteredData():
[... originalArray].sort()
Moreover, since you new state depends on the previous state, you'd better use the syntax:
setState((previousState) => {
// transform previousState
return newState;
})