Почему хук useState возвращает массив, а не объект? Давайте создадим пользовательский хук, чтобы увидеть

Здравствуйте, Вы когда-нибудь задавались вопросом, почему возвращение массивов из функций стало модным в наши дни?

Как мы все знаем, хуки react, такие как useState, useEffect или useRef могут быть использованы только на верхнем уровне компонента и не могут быть использованы внутри функции, пользовательские хуки — это функции, внутри которых мы можем использовать хуки React.

Давайте посмотрим наш пример без использования пользовательских хуков …

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

const Form = () => {
  const [name, setName] = useState(
    JSON.parse(localStorage.getItem("name")) ?? ""
  );
  const [email, setEmail] = useState(
    JSON.parse(localStorage.getItem("email")) ?? ""
  );

  useEffect(() => {
    localStorage.setItem("name", JSON.stringify(name));
  }, [name]);
  useEffect(() => {
    localStorage.setItem("email", JSON.stringify(email));
  }, [email]);
  return (
    <form>
      <input type="text" value={name} onChange={e => setName(e.target.value)} />
      <input
        type="text"
        value={email}
        onChange={e => setEmail(e.target.value)}
      />
      <button>Register</button>
    </form>
  );
};

export default Form;
Вход в полноэкранный режим Выход из полноэкранного режима

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

Поэтому у нас есть состояние для каждого входа, которое инициализируется из сохраненного значения или пустой строки, при изменении мы устанавливаем состояние с новым значением, и у нас есть useEffect для установки значения в localStorage при изменении.

Это хорошо, но давайте построим тот же пример, используя пользовательский хук, чтобы увидеть разницу …

import { useState, useEffect } from "react";

export default function useStoreInput(storageKey) {
  const [value, setValue] = useState(
    JSON.parse(localStorage.getItem(storageKey)) ?? ""
  );

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

  return [value, setValue];
}
Вход в полноэкранный режим Выход из полноэкранного режима

Это просто наш пользовательский хук, это обычная функция, использующая хуки React, мы передаем ей имя ключа localStorage, и она определяет состояние для нас и инициализирует его значением из localStorage, как и раньше, затем она слушает это состояние и сохраняет его в localStorage при изменении.

Как мы видим, мы выбрали возвращать массив [value, setValue], а не объект, мы увидим почему…

Давайте посмотрим, как наш компонент использует наш новый пользовательский хук …

import React from "react";
import useStoreInput from "./useStoreInput";

const Form = () => {
  const [name, setName] = useStoreInput("name");
  const [email, setEmail] = useStoreInput("email");

  return (
    <form>
      <input type="text" value={name} onChange={e => setName(e.target.value)} />
      <input
        type="text"
        value={email}
        onChange={e => setEmail(e.target.value)}
      />
      <button>Register</button>
    </form>
  );
};

export default Form;
Вход в полноэкранный режим Выход из полноэкранного режима

Как мы видим, при использовании пользовательских хуков мы не увидели повторения кода в нашем компоненте, это объясняется двумя причинами …

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

Если бы мы решили возвращать объект вместо массива, наш компонент выглядел бы следующим образом

import React from "react";
import useStoreInput from "./useStoreInput";

const Form = () => {
  const { value: name, setValue: setName } = useStoreInput("name");
  const { value: email, setValue: setEmail } = useStoreInput("email");

  return (
    <form>
      <input type="text" value={name} onChange={e => setName(e.target.value)} />
      <input
        type="text"
        value={email}
        onChange={e => setEmail(e.target.value)}
      />
      <button>Register</button>
    </form>
  );
};

export default Form;
Вход в полноэкранный режим Выйти из полноэкранного режима

Поэтому каждый раз при использовании хука я бы говорил ему переименовать value и setValue новыми именами.

Именно поэтому хук useState() возвращает массив, а не объект

const [counter, setCounter] = useState(0);
Вход в полноэкранный режим Выйти из полноэкранного режима

Поэтому создатели react решили возвращать массив из хука, чтобы было проще деструктурировать возвращаемый массив и определять новые состояния.

Это касается не только хуков, React или даже JavaScript, вы можете думать так же, если используете язык, который поддерживает деструктуризацию.

Возвращать массивы — это здорово, но, конечно, это зависит от вашего случая, допустим, если у нас есть функция, которая возвращает 10 свойств, но мы не всегда используем все свойства, в некоторых случаях мы используем только 8-й элемент, также поддерживать код в этом случае будет очень сложно, поэтому возвращать массив не всегда правильное решение.

Спасибо!

Оцените статью
devanswers.ru
Добавить комментарий