Если вы читали официальную документацию по React (и должны, поскольку это один из замечательных ресурсов по React), вы заметили эти строки:
Независимо от того, объявляете ли вы компонент как функция или класс, он никогда не должен изменять свои собственные свойства.
React довольно гибкий, но у него есть одно строгое правило:
Все компоненты React должны действовать. как чистые функции по отношению к своим свойствам.
Реквизит никогда не обновляется. Мы должны использовать их как есть. Звучит жестко, правда? Но у React есть свои причины, стоящие за этим правилом, и меня вполне убедили их доводы. Однако единственное предостережение заключается в том, что бывают ситуации, когда нам может потребоваться инициировать обновление опоры. И мы скоро узнаем, как это сделать.
Рассмотрим следующую строку кода родительского компонента:
<MyChild childName={this.state.parentName} />
Это простая строка, с которой, вероятно, знаком каждый разработчик React. Вы вызываете дочерний компонент. Пока вы это делаете, вы также передаете состояние родителя (parentName
) потомку. В дочернем компоненте это состояние будет доступно как this.props.childName.
Достаточно справедливо.
Теперь, если требуется какое-либо изменение имени, parentName
будет изменен в родительском элементе, и это изменение будет автоматически передано дочернему элементу, как в случае с механизмом React. Эта установка работает в большинстве сценариев.
Но что, если вам нужно обновить свойство дочернего компонента, а сведения о требуемом изменении и триггер для его изменения известны только дочернему компоненту? Учитывая способы React, данные могут передаваться только сверху вниз, то есть от родителя к потомку. Так как же нам сообщить родителю, что требуется изменение опоры?
Что ж, хотя это антипаттерн и не рекомендуется, разработчики, написавшие этот язык, нас охватили. Сюрприз!
Мы можем сделать это с помощью обратных вызовов. Я знаю, здесь нет ничего удивительного! Кажется, они пригодятся для решения каждой проблемы, с которой мы здесь сталкиваемся. Хорошо, хорошо, как теперь?
Представьте, что приведенный выше вызов дочернего элемента был изменен таким образом:
<MyChild childName={this.state.parentName} onNameChange={this.onChange} />
Теперь в дополнение к опоре childName
у нашего нуждающегося ребенка также есть событие под названием onNameChange
. Это способ решения проблемы. Наш ребенок сделал свое дело. Теперь очередь делать то, что требуется. И не нужно беспокоиться. Все, что ему нужно сделать, это определить функцию onChange
как
function onChange(newName) {
this.setState({ parentName: newName });
}
Вот и все. Теперь всякий раз, когда и где бы в дочернем компоненте мы хотели обновить свойство parentName
, все, что нам нужно сделать, это вызвать `this.props.onNameChange(' My New name')
и вуаля! Вы получите то, что желаете. Вот и все. Готово и присыпано.
Надеюсь, это было легко понять. Сообщите мне в комментариях о любых трудностях или способах, которыми это можно было бы облегчить. Спасибо.
И последнее.
React возражает против этого, и они совершенно правы. Это антипаттерн. Поэтому всякий раз, когда вы сталкиваетесь с подобной ситуацией, проверьте, можете ли вы поднять свое состояние или есть какой-либо способ сломать свой компонент. Это может показаться немного утомительным, но знайте, что именно так и должно быть в React!
Удачного кодирования.