4

I am curious to know which one perform better. Two of the example run correctly without warning, but is it acceptable to declare mutable variable in react without useState ? (Example using react query for data fetching)

Ex 1 :

let flexibleName = ""

const { data, status } = useQuery("users", fetchUsers)

if(data) flexibleName = "TEST DATA"

return <div>{flexibleName}</div>

Ex 2 :

const [flexibleName, setFlexibleName] = useState("")

const { data, status } = useQuery("users", fetchUsers)

useEffect(()=>{
  if(!data) return
  setFlexibleName("TEST DATA")
},[data])

return <div>{flexibleName}</div>
2
  • 1
    This will work, ant in case of performance, there is propablo not a big problem. But you variable will not be rememberet through rerenders, and you lost every data you store in it from user interaction, and if you change it, it will not be seen in html, because it will not cause rerender. Commented Oct 4, 2022 at 7:36
  • and in your ex2, you are setting it wrong, this will be also lost after rerender, because you are not calling setFlexibleName("TEST DATA") Commented Oct 4, 2022 at 7:37

2 Answers 2

5

Is it acceptable to declare mutable variable in react without useState?

Yes, it's ok to do so. flexibleName appears to be derived state (derived from data), and as such doesn't belong in React state. Use the first example.

const { data, status } = useQuery("users", fetchUsers);

const flexibleName = data ? "TEST DATA" : "";

return <div>{flexibleName}</div>;

If you need to you can memoize the flexibleName value with the useMemo hook.

const { data, status } = useQuery("users", fetchUsers);

const flexibleName = useMemo(() => {
  return data ? "TEST DATA" : "";
}, [data]);

return <div>{flexibleName}</div>;

See Identify the Minimal (but complete) Representation of UI State for more details regarding derived state.

Ask three questions about each piece of data:

  1. Is it passed in from a parent via props? If so, it probably isn’t state.
  2. Does it remain unchanged over time? If so, it probably isn’t state.
  3. Can you compute it based on any other state or props in your component? If so, it isn’t state.

Note the emphasis is mine.

Computing the derived state also avoids the unnecessary rerenders just to update some state for display. Or another way to think about it is that the useMemo hook is like combining the useState and useEffect hooks to update and memoize a value without triggering the additional rerender.

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

Comments

1

In this case, it is actually better to not use state.

As explained in this article from the React team, using a state will cause an unnecessary rerender of the component when the flexibleName variable is modified.
Quoting the documentation:

If you can calculate some information from the component’s props or its existing state variables during rendering, you should not put that information into that component’s state.

Also, in your example, the setFlexibleName is a function to you should call it like setFlexibleName("TEST DATA")

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.