10

Is there any syntax that would allow assigning useState outside of the function component? I have tried this so far but it has not worked:

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function App() {
  useEffect(() => setStateData("from useEffect"), []);

  return <div className="App">{stateData}</div>;
}

const [stateData, setStateData] = App.useState("default value"); // fails
// const [stateData, setStateData] = App.prototype.useState("default value"); // also fails

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

CodeSandbox: Edit objective-worker-qb20h

3
  • Why you want to do that? useState isn't supposed to work that way, maybe you want to do something else and can be done without using useState outside a functional component. Commented Dec 16, 2019 at 17:23
  • 1
    Mostly for my own understanding of how React works, but possibly for code organization if I like the separation. Commented Dec 16, 2019 at 17:24
  • Short answer, no, as this is not how React Hooks work Commented Dec 16, 2019 at 17:25

3 Answers 3

20

Disclaimer: This is an anti-pattern¹. If you wanna share state there's better ways, but just for info…

You can use the useState's update function outside of a component by assigning it to a variable. Just be sure to clear it when the component unmounts.

/* Reference to hold the update function */
let updateOutside

function App() {
  const [state, update] = useState()
  
  useEffect(() => {
    /* Assign update to outside variable */
    updateOutside = update

    /* Unassign when component unmounts */
    return () => updateOutside = null
  })

  return `App State: ${state}`
}

if (updateOutside) updateOutside(/* will re-render App */)

¹This code is an anti-pattern as it violates the principles of React's data flow by using a global variable to store a state update function, which can lead to unpredictable behavior and make the code harder to maintain and debug. Instead, it's recommended to use React's built-in mechanisms for managing state and passing data between components, such as props and context.

Sign up to request clarification or add additional context in comments.

2 Comments

Is there any documentation or article explaining in detail why this is an anti-pattern?
@CùĐứcHiếu Good question. The official docs say specifically to "Only Call Hooks from React Functions". Other than that, it just doesn't seem intuitive.
11

Is there any syntax that would allow assigning useState outside of the function component?

If you take a look at the docs and Rules of Hooks

Only Call Hooks from React Functions

Don’t call Hooks from regular JavaScript functions. Instead, you can:

✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page).

So... no, you can't use useState outside of a functional component.

2 Comments

From that page, it looks like wrapping the useState() call in another function does it (a "custom hook"). Is that accurate?
@SeanDezoysa Yes, it becomes a custom hooks, but you can only call custom hooks inside functional components
1

If you want to use useState outside of components think about using https://jotai.org/

It's useState replacement with some additional bonuses

 import { atom, useAtom } from 'jotai'

// Create your atoms and derivatives
const textAtom = atom('hello')
const uppercaseAtom = atom(
  (get) => get(textAtom).toUpperCase()
)

// Use them anywhere in your app
const Input = () => {
  const [text, setText] = useAtom(textAtom)
  const handleChange = (e) => setText(e.target.value)
  return (
    <input value={text} onChange={handleChange} />
  )
}

const Uppercase = () => {
  const [uppercase] = useAtom(uppercaseAtom)
  return (
    <div>Uppercase: {uppercase}</div>
  )
}

// Now you have the components
const App = () => {
  return (
    <>
      <Input />
      <Uppercase />
    </>
  )
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.