Как создать функцию, которая копирует useState () [1] с машинописным текстом? - PullRequest
0 голосов
/ 20 июня 2020

Что я хочу сделать:

Я создаю собственный хук, и я хочу создать функцию, которая будет эквивалентна useState()[1], что означает, эквивалентную функции setState из useState.

const setMyState = value => { ... }

И value может быть либо значением для обновления, либо функцией, которая получит предыдущее состояние и вернет обновленное значение.

Но какой тип я должен использовать для это?

Пример и ожидания того, что я пытаюсь

Единственный пример, который я пытаюсь сделать, - это создать хук useLocalStorage в машинописном тексте.

Где то, что я сделал до сих пор

// what should this type be?
type Foo = ???
type Bar = ???

function useLocalStorage<T>(key: string, initialValue: T): [T, Foo] {
  // State to store our value
  // Pass initial state function to useState so logic is only executed once
  const [storedValue, setStoredValue] = useState<T>(() => {
    try {
      // Get from local storage by key
      const item = window.localStorage.getItem(key);
      // Parse stored json or if none return initialValue
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // If error also return initialValue
      console.log(error);
      return initialValue;
    }
  })

  // Return a wrapped version of useState's setter function that ...
  // ... persists the new value to localStorage.
  const setValue: Foo = (value: Bar) => {
    try {
      // Allow value to be a function so we have same API as useState
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;
      // Save state
      setStoredValue(valueToStore);
      // Save to local storage
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      // A more advanced implementation would handle the error case
      console.log(error);
    }

  }

  return [storedValue, setValue];
}

export default useLocalStorage

То, что я пробовал до сих пор

Я пытался поставить React.SetStateAction<T>, что мне нужно для setValue

type SetStateAction<S> = S | ((prevState: S) => S);

Но похоже, что это не работает, и это дает мне ошибку

function useLocalStorage<T>(key: string, initialValue: T): [T, React.SetStateAction<T>] {
    ...
    const setValue: React.SetStateAction<T> = (value: React.SetStateAction<T>) => { ... }
}

Type '(value: React.SetStateAction) => void' не присваивается типу SetStateAction. Тип '(value: React.SetStateAction) => void' не может быть присвоен типу '(prevState: T) => T'. Тип void не может быть назначен типу T.

Но я действительно не понимаю, почему, может кто-нибудь объяснить, что не так, где?

1 Ответ

2 голосов
/ 20 июня 2020

useState()[1] возвращает тип React.Dispatch<React.SetStateAction<T>>. Думаю, вы хотели реализовать вот так:

type Foo<T> = React.Dispatch<React.SetStateAction<T>>;
type Bar<T> = React.SetStateAction<T>

Полный код:

function useLocalStorage<T>(key: string, initialValue: T): [T, Foo<T>] {
  // State to store our value
  // Pass initial state function to useState so logic is only executed once

  const [storedValue, setStoredValue] = React.useState<T>(() => {
    try {
      // Get from local storage by key
      const item = window.localStorage.getItem(key);
      // Parse stored json or if none return initialValue
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      // If error also return initialValue
      console.log(error);
      return initialValue;
    }
  });

  // Return a wrapped version of useState's setter function that ...
  // ... persists the new value to localStorage.
  const setValue: Foo<T> = (value: Bar<T>) => {
    try {
      // Allow value to be a function so we have same API as useState
      const valueToStore =
        value instanceof Function ? value(storedValue) : value;
      // Save state
      setStoredValue(valueToStore);
      // Save to local storage
      window.localStorage.setItem(key, JSON.stringify(valueToStore));
    } catch (error) {
      // A more advanced implementation would handle the error case
      console.log(error);
    }
  };

  return [storedValue, setValue];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...