| Use Case | Alternative |
|---|---|
| Updating state based on props or state Caching expensive calculations Transforming data |
Compute on each render, consider a memo if expensive. |
| Resetting all state when a prop changes | Use key prop to reset state. |
| Adjusting some state when a prop changes | Compute on each render, consider a memo if expensive. If unavoidable (e.g. new state depends on previous state or props) call setState directly during render. |
| Sharing logic between event handlers | Put the shared logic into a function that you call from both event handlers. |
| Sending a POST request Responding to an event handler Responding to user events |
Use event handlers, or state transitions. |
| Chains of computations | Calculate what you can during rendering, and adjust the state in the event handler. |
| Notifying parent components about state changes Passing data to the parent Communicating with parents |
Move calls to parent props in to event handlers. |
| Subscribing to an external store Interacting with browser APIs |
useSyncExternalStore. |
| Fetching data | react-query, react-router, apollo-client, useLoaderData, getServerSideProps, RSC, SWR, use, react-async, use-async-query, react-hooks-fetch. |
| Initializing the application Initializing global singletons |
Call them outside of the component. |
| Synchronization Effects ("Effects that are caused by rendering itself rather than by a particular event") | ✅ |
Footnotes
-
Using useEffect Effectively by David Khourshid (slides) ↩