Надеюсь, вы лучше понимаете основы React Hooks. Если вы не знакомы с тем, почему и что насчет React Hooks and Basics, я настоятельно рекомендую вам прочитать первую статью из этой серии статей и следовать дальше, чтобы глубоко понять все о React Hooks и их использовании.

Синтаксис и использование

const [ state, setState ] = useState(initialState);

Как объясняется в Официальном документе, hook - это уникальный вид функции, которая позволяет нам подключаться к функциям React.

Если мы посмотрим на приведенный выше синтаксис ловушки useState, вы увидите, что он возвращает пару значений, представляющих текущее состояние, и функцию, которая позволяет мы обновляем состояние соответственно.

useState FAQ

Что происходит при вызове useState?

Когда мы вызываем useState, он объявляет «переменную состояния» по указанному нами имени. В приведенном выше примере мы назвали его «состоянием», но мы можем иметь любое имя, какое захотим. (например, яблоко, банан или что-нибудь еще). Также для функции, возвращаемой useState, может быть любое имя по вашему желанию (например, setAppleCoune и т. Д.)

const [ banana, setBananaList ] = useState(initialState);

Если вы пришли из фона JavaScript, как вы знаете, как только вы вызываете и завершаете выполнение функции, все значения, связанные с этой функцией, также «исчезают» после выполнения. Но с помощью хуков React гарантирует, что это значение переменной состояния сохраняется даже после повторной визуализации (то есть нескольких вызовов функций).

Что мы передаем в useState?

Он принимает один аргумент и может иметь любое значение. Например, логическое значение, int, массив, null, undefined и т. Д. Или даже объект.

const initialState = [];
const [bananaList, setBananaList] = useState(initialState);

Что возвращает useState?

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

Что происходит при первоначальном рендеринге:

Во время первоначального рендеринга возвращаемое состояние (state) совпадает со значением, переданным в качестве первого аргумента (initialState).

const initialState = [];
const [bananaList, setBananaList] = useState(initialState);
console.log(bananaList); // Output --> []

Что произойдет, если мы вызовем setState функцию после первоначального рендеринга:

setBananaList([{id: 1, bananaName:'Red Banana'}]);
console.log(bananaList);// Output [{id: 1, bananaName:'Red Banana'}]

Он обновит значение состояния до нового значения, а затем поставит в очередь повторную визуализацию компонента.

Если он вызывается после первоначального рендеринга, первое возвращаемое значение будет самым последним после выполненных обновлений.

Использование useState Hook

Надеюсь, у вас есть базовые представления об использовании ловушки состояния, теперь давайте рассмотрим пару примеров использования ловушки useState в приложениях. Вы можете использовать этот useState хук по-разному:

Использование одной переменной состояния:

const Counter = ({ initialCount = 0 }) => {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>
         Reset
      </button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>
         -
      </button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>
         +
      </button>
    </>
  );
}

Использование нескольких переменных состояния:

const UserInput = () => {
  const [age, setAge] = useState('');
  const [name, setName] = useState('');

  return (
    <div>
      <input
         type="number"
         value={age}
         placeholder="Enter age"
         onChange={e => setAge(e.target.value)}
      />
      <p>
        <strong>My Age : {age}</strong>
      </p>
      <input
         type="text"
         value={name}
         placeholder="Enter name"
         onChange={e => setName(e.target.value)}
      />
      <p>
        <strong>My Name : {name}</strong>
      </p>
   </div>
  );
};

Использование нескольких переменных в одной переменной состояния:

const UserInput = () => {
  const [state, setState] = useState({ name: '', age: '' });
  const { name, age } = state;
return (
    <div>
       <input
         type="number"
         value={age}
         placeholder="Enter age"
         onChange={e => setState({ ...state, age: e.target.value })}
       />
       <p>
         <strong>My Age : {age}</strong>
       </p>
       <input
         type="text"
         value={name}
         placeholder="Enter name"
         onChange={e => setState({...state, name: e.target.value})}
       />
       <p>
         <strong>My Name : {age}</strong>
       </p>
   </div>
  );
};

Ленивое начальное состояние

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

const [state, setState] = useState(() => {
  const initialState = expensiveComputationForInitialState(props);
  return initialState;
});

Я надеюсь, что охватил почти все концепции и ошибки, связанные с хуком useState. Если у вас есть вопросы по этому поводу, задавайте их в разделе комментариев.

Далее в серии: useEffect Hook