Преобразование компонента класса в функциональный

#reactjs #react-hooks

#reactjs ( реакция ) #реагирующие хуки #reactjs

Вопрос:

Вот пример некоторого кода наhttps://codepen.io/vasilly/pen/LkZKzj

Я пытаюсь выяснить, как изменить основной класс на функциональный компонент, но я застрял на том, как преобразовать

 setCategory(category) {
    this.setState({
      displayCategory: category
    });
  }
  

в строках 72 — 76.

Есть ли у кого-нибудь какие-либо предложения о том, как этого добиться? Я новичок в react и пытаюсь найти наилучший способ сделать это.

Ответ №1:

методы состояния могут быть заменены перехватчиками реакции, в частности, перехватчиком useState

Я рекомендую вам ознакомиться с документами, но основные моменты, которые следует иметь в виду, это

  • там нет this (так что больше нет .bind(this) !)
  • все является функциями

и правила игры с крючками

  • перехваты могут быть вызваны только из функций react (не из простых js функций). То есть вызывать их из функциональных компонентов или других перехватов
  • хуки должны вызываться всегда в одном и том же порядке, что означает, что вы не можете условно вызывать хуки (например, внутри if ) или в циклах). Из-за этого они также должны вызываться на «верхнем» уровне компонента (что означает, что они не могут быть вызваны внутри функции, определенной в вашем компоненте)

Имея это в виду, давайте посмотрим, как бы вы заменили состояние. Для этого вы можете использовать useState крючок.

 const [displayCategory, setDisplayCategory] = useState('all');
  

Уникальный параметр — это начальное значение для вашего состояния. Этот параметр необязателен, если значение по умолчанию не указано, это будет то же самое, что и предоставление undefined .
Как вы можете видеть, он возвращает массив из двух элементов, то, что мы здесь делаем, является деструктурированием; это то же самое, что и выполнение

 const stateHook = useState('all')
const displayCategory = stateHook[0]
const setDisplayCategory= stateHook[1]
  

Это означает, что вы можете называть эти переменные как угодно.
Теперь displayCategory — это ваше фактическое значение состояния. Вы можете использовать его так, как вы бы использовали this.state.displayCategory . И setDisplayCategory — это функция, которая позволяет вам обновлять свое состояние.

Одно из отличий, которое следует иметь в виду, заключается в том, что функции для обновления состояния в перехватах переопределяют все состояние — это означает, что нет слияния состояний, как это было в классах. Это особенно важно для объектов. Итак, что-то вроде этого

 const [state, setState] = useState({ foo: 1, baz: 2 })
// later in one event
setState({ baz: 3 })
  

Там, при следующем рендеринге, значение state будет { baz: 3 } — предыдущее было потеряно

Чтобы сохранить состояние, второй параметр из массива, возвращаемый из useState (имеется в виду setState , setDisplayCategory или как вы его называете), принимает обратный вызов, в котором вы можете вручную выполнить объединение свойств. Вот так

 setState(prevState => ({ ...prevState, baz: 3 })
  

Теперь, при следующем рендеринге, значение вашего состояния будет { foo: 1, baz 3 }

Моделирование сложных состояний

До перехватов у вас могло быть только одно состояние. Следовательно, все, что вы хотели сохранить в своем состоянии, должно было принадлежать этому уникальному объекту. Однако с помощью перехватов вам разрешено иметь несколько состояний. Например, следуя вашему коду, вы могли бы получить что-то вроде этого

 const [displayCategory, setDisplayCategory] = useState('all')
const [products, setProducts] = useState([])
const [myComplexObject, setMyComplexObject] = useState({ foo: 1, baz: 2, bar: [1, 2, 3] })
  

Учитывая это, а также тот факт, что свойства не объединяются автоматически, удобно группировать объекты состояния / переменные / свойства, которые изменяются вместе под одним и тем же useState объектом. Это дает больше гибкости, особенно при передаче разных частей вашего состояния разным дочерним компонентам — вы могли бы сохранить некоторые повторные отправки, когда для этих компонентов реквизиты не меняются

Комментарии:

1. Спасибо вам за подробный ответ. Пока мне кажется, что это имеет смысл, возможно, я запутываюсь из-за количества компонентов, используемых в моем примере. Я пытаюсь следовать дальше: codepen.io/meaghanbass/pen/RwaMGee Я не уверен, почему продукты не отображаются сейчас. Я гораздо больше привык использовать компоненты класса, поэтому приношу извинения за то, что у меня пока не совсем все получается.

2. вам не хватает передачи некоторых реквизитов (компонент пользовательского интерфейса ничего не получает), и вам нужно выполнить импорт useState из react (это именованный экспорт)

Ответ №2:

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

 const [displayCategory, setDisplayCategory] = useState('defaultStateValue');
const setCategory = (category) => {
    setDisplayCategory(category);
}
  

В приведенном выше фрагменте кода вы просто инициализируете свои переменные состояния и функцию установки переменных состояния с помощью useState() крючка. Затем вы вызываете setDisplayCategory() и передаете ему параметр, до которого вы хотите обновить свою переменную состояния displayCategory . Вы должны инициализировать все другие переменные состояния в Main компоненте аналогичным образом.

Вы должны прочитать больше о крючках здесь —https://reactjs.org/docs/hooks-intro.html и ознакомьтесь с ними, поскольку они часто используются в функциональных компонентах,