--- id: hooks-faq title: Hooks FAQ permalink: docs/hooks-faq.html prev: hooks-reference.html --- *Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. This page answers some of the frequently asked questions about [Hooks](/docs/hooks-overview.html). * **[Adoption Strategy](#adoption-strategy)** * [Which versions of React include Hooks?](#which-versions-of-react-include-hooks) * [Do I need to rewrite all my class components?](#do-i-need-to-rewrite-all-my-class-components) * [What can I do with Hooks that I couldn't with classes?](#what-can-i-do-with-hooks-that-i-couldnt-with-classes) * [How much of my React knowledge stays relevant?](#how-much-of-my-react-knowledge-stays-relevant) * [Should I use Hooks, classes, or a mix of both?](#should-i-use-hooks-classes-or-a-mix-of-both) * [Do Hooks cover all use cases for classes?](#do-hooks-cover-all-use-cases-for-classes) * [Do Hooks replace render props and higher-order components?](#do-hooks-replace-render-props-and-higher-order-components) * [What do Hooks mean for popular APIs like Redux connect() and React Router?](#what-do-hooks-mean-for-popular-apis-like-redux-connect-and-react-router) * [Do Hooks work with static typing?](#do-hooks-work-with-static-typing) * [How to test components that use Hooks?](#how-to-test-components-that-use-hooks) * [What exactly do the lint rules enforce?](#what-exactly-do-the-lint-rules-enforce) * **[From Classes to Hooks](#from-classes-to-hooks)** * [How do lifecycle methods correspond to Hooks?](#how-do-lifecycle-methods-correspond-to-hooks) * [Is there something like instance variables?](#is-there-something-like-instance-variables) * [Should I use one or many state variables?](#should-i-use-one-or-many-state-variables) * [Can I run an effect only on updates?](#can-i-run-an-effect-only-on-updates) * [How to get the previous props or state?](#how-to-get-the-previous-props-or-state) * [How do I implement getDerivedStateFromProps?](#how-do-i-implement-getderivedstatefromprops) * [Can I make a ref to a function component?](#can-i-make-a-ref-to-a-function-component) * [What does const [thing, setThing] = useState() mean?](#what-does-const-thing-setthing--usestate-mean) * **[Performance Optimizations](#performance-optimizations)** * [Can I skip an effect on updates?](#can-i-skip-an-effect-on-updates) * [How do I implement shouldComponentUpdate?](#how-do-i-implement-shouldcomponentupdate) * [How to memoize calculations?](#how-to-memoize-calculations) * [How to create expensive objects lazily?](#how-to-create-expensive-objects-lazily) * [Are Hooks slow because of creating functions in render?](#are-hooks-slow-because-of-creating-functions-in-render) * [How to avoid passing callbacks down?](#how-to-avoid-passing-callbacks-down) * [How to read an often-changing value from useCallback?](#how-to-read-an-often-changing-value-from-usecallback) * **[Under the Hood](#under-the-hood)** * [How does React associate Hook calls with components?](#how-does-react-associate-hook-calls-with-components) * [What is the prior art for Hooks?](#what-is-the-prior-art-for-hooks) ## Adoption Strategy ### Which versions of React include Hooks? Starting with 16.8.0, React includes a stable implementation of React Hooks for: * React DOM * React DOM Server * React Test Renderer * React Shallow Renderer Note that **to enable Hooks, all React packages need to be 16.8.0 or higher**. Hooks won't work if you forget to update, for example, React DOM. React Native will fully support Hooks in its next stable release. ### Do I need to rewrite all my class components? No. There are [no plans](/docs/hooks-intro.html#gradual-adoption-strategy) to remove classes from React -- we all need to keep shipping products and can't afford rewrites. We recommend trying Hooks in new code. ### What can I do with Hooks that I couldn't with classes? Hooks offer a powerful and expressive new way to reuse functionality between components. ["Building Your Own Hooks"](/docs/hooks-custom.html) provides a glimpse of what's possible. [This article](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889) by a React core team member dives deeper into the new capabilities unlocked by Hooks. ### How much of my React knowledge stays relevant? Hooks are a more direct way to use the React features you already know -- such as state, lifecycle, context, and refs. They don't fundamentally change how React works, and your knowledge of components, props, and top-down data flow is just as relevant. Hooks do have a learning curve of their own. If there's something missing in this documentation, [raise an issue](https://github.com/reactjs/reactjs.org/issues/new) and we'll try to help. ### Should I use Hooks, classes, or a mix of both? When you're ready, we'd encourage you to start trying Hooks in new components you write. Make sure everyone on your team is on board with using them and familiar with this documentation. We don't recommend rewriting your existing classes to Hooks unless you planned to rewrite them anyway (e.g. to fix bugs). You can't use Hooks *inside* of a class component, but you can definitely mix classes and function components with Hooks in a single tree. Whether a component is a class or a function that uses Hooks is an implementation detail of that component. In the longer term, we expect Hooks to be the primary way people write React components. ### Do Hooks cover all use cases for classes? Our goal is for Hooks to cover all use cases for classes as soon as possible. There are no Hook equivalents to the uncommon `getSnapshotBeforeUpdate` and `componentDidCatch` lifecycles yet, but we plan to add them soon. It is an early time for Hooks, and some third-party libraries might not be compatible with Hooks at the moment. ### Do Hooks replace render props and higher-order components? Often, render props and higher-order components render only a single child. We think Hooks are a simpler way to serve this use case. There is still a place for both patterns (for example, a virtual scroller component might have a `renderItem` prop, or a visual container component might have its own DOM structure). But in most cases, Hooks will be sufficient and can help reduce nesting in your tree. ### What do Hooks mean for popular APIs like Redux `connect()` and React Router? You can continue to use the exact same APIs as you always have; they'll continue to work. In the future, new versions of these libraries might also export custom Hooks such as `useRedux()` or `useRouter()` that let you use the same features without needing wrapper components. ### Do Hooks work with static typing? Hooks were designed with static typing in mind. Because they're functions, they are easier to type correctly than patterns like higher-order components. The latest Flow and TypeScript React definitions include support for React Hooks. Importantly, custom Hooks give you the power to constrain React API if you'd like to type them more strictly in some way. React gives you the primitives, but you can combine them in different ways than what we provide out of the box. ### How to test components that use Hooks? From React's point of view, a component using Hooks is just a regular component. If your testing solution doesn't rely on React internals, testing components with Hooks shouldn't be different from how you normally test components. If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote. ### What exactly do the [lint rules](https://www.npmjs.com/package/eslint-plugin-react-hooks) enforce? We provide an [ESLint plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) that enforces [rules of Hooks](/docs/hooks-rules.html) to avoid bugs. It assumes that any function starting with "`use`" and a capital letter right after it is a Hook. We recognize this heuristic isn't perfect and there may be some false positives, but without an ecosystem-wide convention there is just no way to make Hooks work well -- and longer names will discourage people from either adopting Hooks or following the convention. In particular, the rule enforces that: * Calls to Hooks are either inside a `PascalCase` function (assumed to be a component) or another `useSomething` function (assumed to be a custom Hook). * Hooks are called in the same order on every render. There are a few more heuristics, and they might change over time as we fine-tune the rule to balance finding bugs with avoiding false positives. ## From Classes to Hooks ### How do lifecycle methods correspond to Hooks? * `constructor`: Function components don't need a constructor. You can initialize the state in the [`useState`](/docs/hooks-reference.html#usestate) call. If computing it is expensive, you can pass a function to `useState`. * `getDerivedStateFromProps`: Schedule an update [while rendering](#how-do-i-implement-getderivedstatefromprops) instead. * `shouldComponentUpdate`: See `React.memo` [below](#how-do-i-implement-shouldcomponentupdate). * `render`: This is the function component body itself. * `componentDidMount`, `componentDidUpdate`, `componentWillUnmount`: The [`useEffect` Hook](/docs/hooks-reference.html#useeffect) can express all combinations of these (including [less](#can-i-skip-an-effect-on-updates) [common](#can-i-run-an-effect-only-on-updates) cases). * `componentDidCatch` and `getDerivedStateFromError`: There are no Hook equivalents for these methods yet, but they will be added soon. ### Is there something like instance variables? Yes! The [`useRef()`](/docs/hooks-reference.html#useref) Hook isn't just for DOM refs. The "ref" object is a generic container whose `current` property is mutable and can hold any value, similar to an instance property on a class. You can write to it from inside `useEffect`: ```js{2,8} function Timer() { const intervalRef = useRef(); useEffect(() => { const id = setInterval(() => { // ... }); intervalRef.current = id; return () => { clearInterval(intervalRef.current); }; }); // ... } ``` If we just wanted to set an interval, we wouldn't need the ref (`id` could be local to the effect), but it's useful if we want to clear the interval from an event handler: ```js{3} // ... function handleCancelClick() { clearInterval(intervalRef.current); } // ... ``` Conceptually, you can think of refs as similar to instance variables in a class. Unless you're doing [lazy initialization](#how-to-create-expensive-objects-lazily), avoid setting refs during rendering -- this can lead to surprising behavior. Instead, typically you want to modify refs in event handlers and effects. ### Should I use one or many state variables? If you're coming from classes, you might be tempted to always call `useState()` once and put all state into a single object. You can do it if you'd like. Here is an example of a component that follows the mouse movement. We keep its position and size in the local state: ```js function Box() { const [state, setState] = useState({ left: 0, top: 0, width: 100, height: 100 }); // ... } ``` Now let's say we want to write some logic that changes `left` and `top` when the user moves their mouse. Note how we have to merge these fields into the previous state object manually: ```js{4,5} // ... useEffect(() => { function handleWindowMouseMove(e) { // Spreading "...state" ensures we don't "lose" width and height setState(state => ({ ...state, left: e.pageX, top: e.pageY })); } // Note: this implementation is a bit simplified window.addEventListener('mousemove', handleWindowMouseMove); return () => window.removeEventListener('mousemove', handleWindowMouseMove); }, []); // ... ``` This is because when we update a state variable, we *replace* its value. This is different from `this.setState` in a class, which *merges* the updated fields into the object. If you miss automatic merging, you can write a custom `useLegacyState` Hook that merges object state updates. However, instead **we recommend to split state into multiple state variables based on which values tend to change together.** For example, we could split our component state into `position` and `size` objects, and always replace the `position` with no need for merging: ```js{2,7} function Box() { const [position, setPosition] = useState({ left: 0, top: 0 }); const [size, setSize] = useState({ width: 100, height: 100 }); useEffect(() => { function handleWindowMouseMove(e) { setPosition({ left: e.pageX, top: e.pageY }); } // ... ``` Separating independent state variables also has another benefit. It makes it easy to later extract some related logic into a custom Hook, for example: ```js{2,7} function Box() { const position = useWindowPosition(); const [size, setSize] = useState({ width: 100, height: 100 }); // ... } function useWindowPosition() { const [position, setPosition] = useState({ left: 0, top: 0 }); useEffect(() => { // ... }, []); return position; } ``` Note how we were able to move the `useState` call for the `position` state variable and the related effect into a custom Hook without changing their code. If all state was in a single object, extracting it would be more difficult. Both putting all state in a single `useState` call, and having a `useState` call per each field can work. Components tend to be most readable when you find a balance between these two extremes, and group related state into a few independent state variables. If the state logic becomes complex, we recommend [managing it with a reducer](/docs/hooks-reference.html#usereducer) or a custom Hook. ### Can I run an effect only on updates? This is a rare use case. If you need it, you can [use a mutable ref](#is-there-something-like-instance-variables) to manually store a boolean value corresponding to whether you are on the first or a subsequent render, then check that flag in your effect. (If you find yourself doing this often, you could create a custom Hook for it.) ### How to get the previous props or state? Currently, you can do it manually [with a ref](#is-there-something-like-instance-variables): ```js{6,8} function Counter() { const [count, setCount] = useState(0); const prevCountRef = useRef(); useEffect(() => { prevCountRef.current = count; }); const prevCount = prevCountRef.current; return