#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 и ознакомьтесь с ними, поскольку они часто используются в функциональных компонентах,