Компонент React инициализирует состояние из реквизитов
в React есть ли реальные различия между этими двумя реализациями? Некоторые друзья говорят мне, что первый компонент-это шаблон, но я не понимаю, почему. Второй компонент кажется проще, потому что рендер вызывается только один раз.
первый:
import React, { PropTypes } from 'react'
class FirstComponent extends React.Component {
state = {
description: ''
}
componentDidMount() {
const { description} = this.props;
this.setState({ description });
}
render () {
const {state: { description }} = this;
return (
<input type="text" value={description} />
);
}
}
export default FirstComponent;
второй:
import React, { PropTypes } from 'react'
class SecondComponent extends React.Component {
state = {
description: ''
}
constructor (props) => {
const { description } = props;
this.state = {description};
}
render () {
const {state: { description }} = this;
return (
<input type="text" value={description} />
);
}
}
export default SecondComponent;
обновление: Я изменил setState () на это.state = {} (спасибо joews), однако, я все еще не вижу разницы. Один лучше другого?
5 ответов:
следует отметить, что это анти-шаблон для копирования свойств, которые никогда не изменяются в состояние (просто доступ .реквизит прямо в таком случае). Если у вас есть переменная состояния, которая в конечном итоге изменится, но начинается со значения from .реквизит, вам даже не нужен вызов конструктора - эти локальные переменные инициализируются после вызова родительского конструктора:
class FirstComponent extends React.Component { state = { x: this.props.initialX, // You can even call functions and class methods: y: this.someMethod(this.props.initialY), }; }
Это сокращенный эквивалент ответа от @joews ниже. Кажется, это работает только на более поздних версии транспилеров es6, у меня были проблемы с ним на некоторых настройках webpack. Если это не работает для вас, не стенографическая версия от @joews будет.
вам не нужно звонить
setState
в компонентеconstructor
- это идиоматично установитьthis.state
напрямую:class FirstComponent extends React.Component { constructor(props) { super(props); this.state = { x: props.initialX }; } // ... }
посмотреть реагировать документов - добавление локального состояния на класс.
нет никакого преимущества для первого метода, который вы описываете. Это приведет к второму обновлению непосредственно перед установкой компонента в первый раз.
обновление для React 16.3 Альфа ввел
static getDerivedStateFromProps(nextProps, prevState)
( docs) в качестве заменыcomponentWillReceiveProps
.getDerivedStateFromProps вызывается после создания экземпляра компонента, а также при получении новых реквизитов. Он должен возвращать объект для обновления состояния или null, чтобы указать, что новые реквизиты не требуют каких-либо обновлений состояния.
обратите внимание, что если родительский компонент вызывает повторную визуализацию вашего компонента, этот метод будет даже если реквизиты не изменились. Вы можете сравнить новые и предыдущие значения, если вы только хотите обрабатывать изменения.
он статичен, поэтому у него нет прямого доступа к
this
(однако он имеет доступ кprevState
, который может хранить вещи, обычно прикрепленные кthis
напримерrefs
)отредактировано, чтобы отразить исправление @ nerfologist в комментариях