I have a parent component. Marketplace.js code-
export default function Marketplace() {
const [filters, setFilters] = useState(
[
{
id: 'commodity',
name: "Commodity",
isSelected: false,
type: "select",
options: ['A', 'B', 'C', 'D', 'E'],
value: null,
availableFor: ['classifieds', 'auction']
}
]
);
return (
<div>
<FilterBar filters={filters} setFilters={setFilters} />
</div>
)
The child component FilterBar.js code-
export default function FilterBar({ filters, setFilters }) {
var copiedFilters = [...filters]
const [newFilters, setNewFilters] = useState(copiedFilters);
const onFilterChange = (e, item) => {
if (e.target.value === '') {
item.isSelected = false;
} else {
item.isSelected = true;
}
item.value = e.target.value;
const updatedFilters = newFilters.map((filter) => {
if (filter.id === item.id) {
return {
...filter,
isSelected: item.isSelected,
value: item.value,
};
} else {
return filter;
}
});
setNewFilters(updatedFilters);
};
......
}
When setNewFilters() is used to set some new values, the ‘filters’ state passed from parent is also changed.
How can I fix this issue?
2
Answers
One possible solution is to use JSON to get a deep copy:
Changing
copiedFilters
now shouldn’t changefilters
or any of it’s values.You are mutating the state when you change the item’s
value
andisSelected
props. Just do this instead:When you do:
You are creating a new array, but the items inside it are exactly the same, so you are still referencing the original state from the parent component.