I recently started using hooks in react and I am often having this problem: I create a first big state which is used by all my component, but some of the smaller parts of my component divide this state and create their own state for simplicity.
For exemple
import React, { useState } from "react";
const initialFilters = {
name: "",
code: ""
};
function Filter({ value, setFilters }) {
const [tempValue, setTempValue] = useState(value);
return (
<input
value={tempValue}
onChange={e => setTempValue(e.target.value)}
onBlur={() => setFilters(tempValue)}
/>
);
}
function App() {
const [filters, setFilters] = useState(initialFilters);
const agents = [
{ name: "bob", code: "123" },
{ name: "burger", code: "3123" },
{ name: "sponge", code: "34" }
];
return (
<div>
<label>Name filter</label>
<Filter
value={filters.name}
setFilters={value =>
setFilters(filters => ({ ...filters, name: value }))
}
/>
<label>Code filter</label>
<Filter
value={filters.code}
setFilters={value =>
setFilters(filters => ({ ...filters, code: value }))
}
/>
<button onClick={() => setFilters(initialFilters)}>Reset filters</button>
<ul>
{agents
.filter(
agent =>
agent.name.includes(filters.name) &&
agent.code.includes(filters.code)
)
.map((agent, i) => (
<li key={i}>
name: {agent.name} - code: {agent.code}
</li>
))}
</ul>
</div>
);
}
export default App;
CodeSandox available here
In this exemple the filters work fine, but their value are not emptied when we use the button Reset.
The filters create their own states to dispatch new state only on blur, and still be controlled. I guess I could use ref here, but I use this exemple to showcase a simple case of state dependant on another state (and therefore on props).
How should I go about implementing this in an idiomatic React way?