Home > Enterprise >  Comparing different approaches of setting initial state
Comparing different approaches of setting initial state

Time:12-31

When initializing state in React, is it bad practice to define functions inside of useState rather than using useEffect? Or is it best to use useMemo?

My understanding is that variables inside useState will be set on the first render of the component. Are there any additional considerations when using functions to set the initial state?

Function

import React, { useState, useEffect } from "react";

export default function Token() {
  const a = 5
  const b = 5

  const findToken = (a,b) => {
    return a*b;
  };

  const [token, setToken] = useState(() => {
    return findToken(a,b);
  });

  return (
    <div>
      <h1>Token: {token}</h1>
    </div>
  );
}

useEffect

import React, { useState, useEffect } from "react";

export default function Token() {
  const a = 5
  const b = 5
  const [token, setToken] = useState();
   
  useEffect(() => {
    setToken(a*b);
  }, []);

  return (
    <div>
      <h1>Token: {token}</h1>
    </div>
  );
}

UseMemo

import React, { useState, useEffect } from "react";

export default function Token() { 
  const a = 5
  const b = 5

  const findToken = (a,b) => {
    return a*b;
  };

  const [token, setToken] = useState(useMemo(() => findToken(a,b), [a,b]));

  return (
    <div>
      <h1>Token: {token}</h1>
    </div>
  );
}

Edit interesting-forest-bs2hvy

CodePudding user response:

If the value will only be set exactly once, and the operation that needs to be performed isn't expensive, then it would make the most sense to avoid state and use only useMemo. For example, code like this:

const [token, setToken] = useState(() => {
    return findToken(a,b);
});

if setToken isn't called elsewhere and the calculation isn't expensive, would always be better refactored to

const token = useMemo(() => findToken(a, b), []);

If the value could be set multiple times depending on logic in your app, state will be needed.

If the operation that calculates the value is expensive enough to cause noticeable delays when rendering, then you might decide to compensate for that by using state, initially render an empty value, and then use useEffect to calculate (and set the state) for the expensive value after the component has been painted to the screen.

If you set state in an effect hook (as opposed to useMemo), keep in mind that that'll cause re-rendering of components lower in the tree, which is sometimes undesirable.

CodePudding user response:

Below I will try to compare some of the approaches you listed for setting initial state.

useState with initializer function

const [token, setToken] = useState(() => {
    return findToken(a,b);
});

You use this approach when findToken is relatively expensive, and using this approach it will be guaranteed that findToken will be executed only once. From the PC


Passing functions inside useState vs using useEffect?

let's have a look at hooks usage and when to use them

useEffect Hook

The useEffect hook is designed to be used for performing side effects, such as fetching data or modifying the DOM, and it is not optimized for setting the initial state. In this case, it would be more efficient to use the useState hook to set the initial state directly

useMemo Hook

The useMemo hook is designed to memoize the value of a function, so that it is only recalculated when one of its dependencies changes. In this case, the findToken function is only calculated once, when the component is first rendered, and its value is cached for future renders. This can be more efficient than using the useEffect hook to set the initial state.

conclusion

The best practice is to set the initial state directly using the useState hook unless you have a specific reason to use the useEffect or useMemo hook.


Usage

To use the useState hook to call a function only once, you can pass an initializer function to useState.

    const [token, setToken] = useState(() => findToken(a,b));
  • Related