Invalid hook call при работе с localStorage

Имеется 3 файла:

  1. Основной компонент
  2. Файл со стейтами, которые забиваются в локальное хранилище
  3. Файл с функцией-ресетом для сброса этих самых стейтов в дефлотные значения

Я импотрирую файл со стейтами в основной компонент и всё ок, но когда я импортирую файл с функцией-ресетом, получаю ошибку "Error: Invalid hook call. Hooks can only be called inside of the body of a function component. "

Почитал документацию по реакту, но понимания ошибки не пришло

  1. Код первого файла
import React from 'react';
import { LocalStorage } from './components/localStorageList'
import { resetLocalStorage } from './components/resetLocalStorage'

function mainComponent() {

    const localState = LocalStorage(); // local storage keys
    const resetState = () => resetLocalStorage(); // reset local storate states

    return (
        <div>
            <button onClick={() => resetState()}>
                 {svgRefreshPage}
           </button>
       </div>
    )
}

  1. Код второго файла
import { useState, useEffect } from 'react';

const useLocalStorageList = (key, defaultValue) => {
    const stored = localStorage.getItem(key);
    const initial = stored ? JSON.parse(stored) : defaultValue;
    const [value, setValue] = useState(initial);

    useEffect(() => {
        localStorage.setItem(key, JSON.stringify(value));
    }, [key, value]);

    return [value, setValue];
};

//local storage keys
export const LocalStorage = () => {

    const [localStorageState, setLocalStorageState] = useLocalStorageList('Timer time', 1800)

    return {localStorageState, setLocalStorageState}
}
  1. Код третьего файла
import { LocalStorage } from './localStorageList'

const localState = LocalStorage(); //local storage keys

export const resetLocalStorage = () => {

    localState.setTimerValue(1800)
}

Ссылка на sandbox


Ответы (2 шт):

Автор решения: Qwertiy
const localState = LocalStorage(); //local storage keys

Этот вызов кривой. Он вообще вне компонента.

→ Ссылка
Автор решения: Grundy

У хуков есть ограничения, на то, где их можно вызывать:

  1. непосредственно внутри функции компонента
  2. непосредственно внутри другого хука

Также рекомендуют называть их начиная с use, эта договоренность позволяет реакту проверять правильность вызова и пользовательских хуков.

В коде в вопросе, вызов хука LocalStorage в третьем файле происходит вне компонента либо другого хука, отсюда и ошибки.

Кроме того, в данном случае нет смысла разделять действия над хранилищем на два файла, и достаточно просто объявить метод reset внутри LocalStorage, в этом случае код может выглядеть так:

export const LocalStorage = () => {
  const [localStorageState, setLocalStorageState] = useLocalStorageList(
    "State",
    "Default Value"
  );

  const resetLocalStorageState = () => {
    setLocalStorageState("Default Value");
  };

  return [localStorageState, setLocalStorageState, resetLocalStorageState];
};

И в использовании

function App() {
  const [value, update, reset] = LocalStorage(); // local storage keys

  return (
    <div>
      <button onClick={reset}>Refresh State to default</button>
      <br />
      <button onClick={() => update("State was changed")}>Change State</button>
      <p>{value}</p>
    </div>
  );
}

Пример в песочнице: https://codesandbox.io/s/amazing-feather-1mtgg?file=/src/localState.jsx

→ Ссылка