новый процесс жизненного цикла
Давайте посмотрим на диаграмму жизненного цикла последней версии реакции:
getDerivedStateFromProps
Именование жизненного цикла React всегда было очень семантическим, смысл этого жизненного цикла в том, чтобы получить состояние из реквизита, который, можно сказать, слишком прост и понятен.
Можно сказать, что функция этого жизненного цикла на самом деле состоит в том, чтобы отображать входящие реквизиты в состояние.
Из-за изменений в 16.4 эта функция будет вызываться перед каждым повторным рендерингом, что это значит?
Это означает, что даже если ваши реквизиты не изменились, но родительское состояние изменилось, что привело к повторному рендерингу дочернего компонента, эта функция жизненного цикла все равно будет вызываться. Казалось бы, очень маленькая модификация, она может привести к множеству скрытых проблем.
использовать
Эта функция жизненного цикла существует для замены componentWillReceiveProps, поэтому, когда вам нужно использовать componentWillReceiveProps, вы можете вместо этого использовать getDerivedStateFromProps.
Параметры у них разные, а getDerivedStateFromProps — это статическая функция, то есть эта функция не может получить доступ к свойствам класса через this, и не рекомендуется напрямую обращаться к свойствам. Вместо этого он должен оцениваться по nextProps и prevState, предоставленным параметрами, и сопоставляться с состоянием в соответствии с новыми входящими реквизитами.
Следует отметить, что если содержимое, переданное в props, не должно влиять на ваше состояние, то вам нужно вернуть null, это возвращаемое значение обязательно, поэтому попробуйте написать его в конце функции.
static getDerivedStateFromProps(nextProps, prevState) {
const {type} = nextProps;
// 当传入的type发生变化的时候,更新state
if (type !== prevState.type) {
return {
type,
};
}
// 否则,对于state不进行任何操作
return null;
}
getDerivedStateFromProps exists for only one purpose. It enables a component to update its internal state as the result of changes in props.
Из приведенного выше предложения мы можем ясно понять, что функция getDerivedStateFromProps заключается в том, чтобы разрешить обновление свойств до внутреннего состояния компонента. Таким образом, есть два возможных сценария использования:
Безоговорочно обновлять внутреннее состояние в соответствии с реквизитом, то есть, пока есть входящее значение реквизита, обновлять состояние
Значение состояния обновляется только в том случае, если значение свойства и значение состояния отличаются.
Далее рассмотрим несколько примеров.
Предположим, у нас есть табличный компонент, который обновляет представление на основе входящих данных списка.
class Table extends React.Component {
state = {
list: []
}
static getDerivedStateFromProps (props, state) {
return {
list: props.list
}
}
render () {
.... // 展示 list
}
}
Приведенный выше пример является первым сценарием использования, но для безусловного обновления состояния из свойства нам вообще не нужно использовать этот жизненный цикл, просто оперируйте значением свойства напрямую, не нужно сохранять его с классом значения состояния.
Глядя на пример, этот пример представляет собой средство выбора цвета, этот компонент может выбирать соответствующий цвет и отображать его, а также может отображать цвет в соответствии с переданным значением реквизита.
Class ColorPicker extends React.Component {
state = {
color: '#000000'
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.color) {
return {
color: props.color
}
}
return null
}
... // 选择颜色方法
render () {
.... // 显示颜色和选择颜色操作
}
}
Теперь мы можем выбрать цвет с помощью этой палитры цветов, передать значение цвета и отобразить его. Но у этого компонента есть ошибка: если мы передадим значение цвета, а затем воспользуемся методом выбора цвета внутри компонента, мы обнаружим, что цвет не изменится, это всегда будет входящее значение цвета.
Это распространенная ошибка при использовании этого жизненного цикла. Почему возникает этот баг? Как упоминалось в начале, в версии React 16.4^ setState и forceUpdate также будут запускать этот жизненный цикл, поэтому после изменения внутреннего состояния он перейдет к методу getDerivedStateFromProps и обновит значение состояния для входящего свойства.
Далее мы исправим эту ошибку.
Class ColorPicker extends React.Component {
state = {
color: '#000000',
prevPropColor: ''
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.prevPropColor) {
return {
color: props.color
prevPropColor: props.color
}
}
return null
}
... // 选择颜色方法
render () {
.... // 显示颜色和选择颜色操作
}
}
Сохранив предыдущее значение реквизита, мы можем изменить состояние только при изменении реквизита. Это решает вышеуказанную проблему.
Вот краткое изложение моментов, которые следует учитывать при использовании метода getDerivedStateFromProps:
-
При использовании этого жизненного цикла будьте осторожны, чтобы сравнить входящее значение свойства с ранее переданным свойством.
-
Потому что этот жизненный цикл является статическим методом и в то же время сохраняет его чистую функцию без побочных эффектов.