I have a functional component using Hooks:
function Component(props) {
const [ items, setItems ] = useState([]);
// In a callback Hook to prevent unnecessary re-renders
const handleFetchItems = useCallback(() => {
fetchItemsFromApi().then(setItems);
}, []);
// Fetch items on mount
useEffect(() => {
handleFetchItems();
}, []);
// I want this effect to run only when 'props.itemId' changes,
// not when 'items' changes
useEffect(() => {
if (items) {
const item = items.find(item => item.id === props.itemId);
console.log("Item changed to " item.name);
}
}, [ items, props.itemId ])
// Clicking the button should NOT log anything to console
return (
<Button onClick={handleFetchItems}>Fetch items</Button>
);
}
The component fetches some items
on mount and saves them to state.
The component receives an itemId
prop (from React Router).
Whenever the props.itemId
changes, I want this to trigger an effect, in this case logging it to console.
The problem is that, since the effect is also dependent on items
, the effect will also run whenever items
changes, for instance when the items
are re-fetched by pressing the button.
This can be fixed by storing the previous props.itemId
in a separate state variable and comparing the two, but this seems like a hack and adds boilerplate. Using Component classes this is solved by comparing current and previous props in componentDidUpdate
, but this is not possible using functional components, which is a requirement for using Hooks.
What is the best way to trigger an effect dependent on multiple parameters, only when one of the parameters change?
PS. Hooks are kind of a new thing, and I think we all are trying our best to figure out how to properly work with them, so if my way of thinking about this seems wrong or awkward to you, please point it out.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…