Reputation: 7092
I recently started using react hooks a lot.
State management seems more intuitive to me when using "React.useState".
Anyway, while it's working ok, I know it's starting to look cluttered the more values I am starting to save to state.
For example, as my car parts app has progressed, it is now looking like this:
const [isShown, setIsShown] = React.useState(false);
const [idVal, setIdValue] = React.useState(false);
const [partNameVal, setPartNameValue] = React.useState(false);
const [engineEngineEngineTypeVal, setEngineEngineTypeValue] = React.useState(false);
const [displacementVal, setDisplacementValue] = React.useState(false);
const [makeVal, setMakeValue] = React.useState(false);
const [countryVal, setCountryValue] = React.useState(false);
const hide = () => setIsShown(false);
const show = (id, partName, engineEngineType, displacement, department, country) => {
setIsShown(true);
setIdValue(id);
setPartNameValue(partName);
setEngineTypeValue(engineEngineType);
setDisplacementValue(displacement);
setMakeValue(department);
setCountryValue(country);
}
<p>ID: {idVal}</p>
<p>PartName: {partNameVal}</p>
<p>EngineType: {engineEngineTypeVal}</p>
<p>Displacement: {displacementVal}</p>
<p>Make: {makeVal}</p>
<p>Country: {countryVal}</p>
I was wondering if there's a way to make this more readable, but still be very intuitive.
Thanks!
Upvotes: 2
Views: 2076
Reputation: 53874
Typically you want to handle a single object or use useReducer
, something like:
const INITIAL_CAR = {
id: 0,
part: "4xE3",
country: "USA",
// ... More entries
};
const CarApp = () => {
const [car, setCar] = useState(INITIAL_CAR);
const [isShown, setIsShown] = useState(false);
const show = (carProps) => {
setIsShown(true);
setCar(carProps);
};
const { id, part, engine, displacement, make, county } = car;
const updateCountry = (country) =>
setCar((prevCar) => ({ ...prevCar, country }));
const updateCarProperty = ({ property, value }) =>
setCar((prevCar) => ({ ...prevCar, [property]: value }));
return (
<div>
{isShown && (
<>
<p>ID: {id}</p>
<p>PartName: {part}</p>
<p>EngineType: {engine}</p>
<p>Displacement: {displacement}</p>
<p>Make: {make}</p>
<p>Country: {country}</p>{" "}
</>
)}
// use show, updateCountry, updateProperty etc.
</div>
);
};
Upvotes: 3
Reputation: 2178
You can make a new file to extract all your hook logic from your component.
Call if for example useHooks.js
export default () => {
const [isShown, setIsShown] = React.useState(false);
const [idVal, setIdValue] = React.useState(false);
const [partNameVal, setPartNameValue] = React.useState(false);
const [engineEngineEngineTypeVal, setEngineEngineTypeValue] = React.useState(false);
const [displacementVal, setDisplacementValue] = React.useState(false);
const [makeVal, setMakeValue] = React.useState(false);
const [countryVal, setCountryValue] = React.useState(false);
const hide = () => setIsShown(false);
const show = (id, partName, engineEngineType, displacement, department, country) => {
setIsShown(true);
setIdValue(id);
setPartNameValue(partName);
setEngineTypeValue(engineEngineType);
setDisplacementValue(displacement);
setMakeValue(department);
setCountryValue(country);
}
return [isShown, idVal, partNameVal, engineEngineEngineTypeVal, displacementVal,
makeVal, countryVal, show, hide];
}
The idea was here to put all your hooks logic in a function and return values that you need inside your JSX.
And in your component import and use all properties exported from useHooks
import useHooks from './useHooks';
const [isShown, idVal, partNameVal, engineEngineEngineTypeVal, displacementVal,
makeVal, countryVal, show, hide] = useHooks();
Hope the idea is clear
Upvotes: 1
Reputation: 765
The way I mostly handle this much of state in a component is using one useState
, that way it's just a big object.
Here is a small example :
const [state, setState] = useState({
num: 1,
cars: ['volvo', 'mazda'],
john: {name: 'John', last: 'Foo'}
})
And if you want to change something in that I usually use this function
const onChange = (name, value) => {
setState(prevState => ({...prevState, [name]: value}))
}
This will change the key name
to the value value
. This is way clearer in my eyes.
Upvotes: 1
Reputation: 72
I'd say that it's the case for useReducer
hook.
https://reactjs.org/docs/hooks-reference.html#usereducer
const initialState = {
isShown: false,
idVal: 0,
....
};
function reducer(state, action) {
switch (action.type) {
case 'show':
return {
...state,
isShown: true,
idVal: action.payload.idVal
};
case 'hide':
return {
...state,
isShown: false
}
...
default:
throw new Error();
}
}
const [state, dispatch] = useReducer(reducer, initialState);
dispatch({type: 'show', payload: { idVal: 1}})
Upvotes: 3