Andrii Radkevych
Andrii Radkevych

Reputation: 3442

Prevent custom hook from reinitialization on each re-render

import React, { useState } from "react";

import useInterval from "use-interval";

const useOwnHook = () => {
  const arr = [...Array(100)].map((_, index) => index);

  return {
    arr
  };
};

const Component = ({ count }) => {
  const { arr } = useOwnHook();
  console.log(arr, "arr");
  return (
    <div className="App">
      <h1>{count + 1}</h1>
    </div>
  );
};

export default function App() {
  const [count, setCount] = useState(0);

  useInterval(() => {
    setCount(count + 1);
  }, 1000);

  return <Component count={count} />;
}

I've created hook useOwnHook for demonstration that each time Component re-render, each time it goes insite useOwnHook, and create new array, is it possible to prevent it to move inside of this hook each time on re-render?

Upvotes: 1

Views: 2028

Answers (2)

norbitrial
norbitrial

Reputation: 15176

You can add useState into your custom hook as:

const useOwnHook = () => {
  const [arr] = useState([...Array(100)].map((_, index) => index));

  return {
    arr
  };
};

By doing this you can keep the same array in your useOwnHook.

Also you can import as import { useState } from 'react'.

See also from the Using the State Hook documentation - example with a different variable:

We declare a state variable called count, and set it to 0. React will remember its current value between re-renders, and provide the most recent one to our function. If we want to update the current count, we can call setCount.

Upvotes: 1

Adam Jenkins
Adam Jenkins

Reputation: 55792

Personally, I'd use a state variable with a init function:

const useOwnHook = () => {
  const [arr] = useState(() => [...Array(100)].map((_, index) => index));

  return {
    arr
  };
};

Benefit of the init function is that it's lazy-evaluated so you won't be constructing the array each time the component is rendered.

Upvotes: 1

Related Questions