При установке состояния компонента из реквизита
Недавно я работал над Root Route (в стадии разработки), приложением MERN, целью которого является обеспечение недорогой дорожной карты на пути к тому, чтобы стать веб-разработчиком. Подумайте о Duolingo для веб-разработчиков или о платных функциях Paths от Codecademy.
Мы используем React для пользовательского интерфейса и экспериментируем с различными способами установки состояния в компонентах, которые получают реквизиты. Я рассмотрю несколько методов.
Быстрые обращения - JSX
1. Синтаксис JSX позволяет нам смешивать Javascript и HTML в уникальный инструмент для React. Приведенный ниже код отобразит на странице строку «Hello, World» (после добавления операторов импорта и экспорта вверху и внизу соответственно).
class App extends Component {
render() {
const hello = "Hello, World";
return (
<div>
<p>{hello}</p>
</div>
);
}
}
2. Мы также можем вызывать отдельные компоненты внутри других компонентов. Приведенный ниже фрагмент также отобразит на странице «Hello, World» благодаря операторам return.
class App extends Component {
render() {
return (
<div>
<Helloworld />
</div>
);
}
}
class Helloworld extends Component {
render() {
const hello = "Hello, World";
return (
<p>{hello}</p>
);
}
}
Быстрые хиты - Реквизит
3. Если в компоненте «Helloworld» мы хотим вызвать значения, хранящиеся в компоненте «App», мы можем передать это значение как реквизиты, используя приведенный ниже синтаксис ES6. Свойства используются в React для передачи данных от родительского компонента к дочернему компоненту.
class App extends Component {
render() {
const hello = "Hello, World";
return (
<div>
<Helloworld helloprop={hello} />
</div>
);
}
}
const Helloworld = props => <p>{props.helloprop}</p>;
4. НО мы также можем обойтись без пропуска props без указания его в качестве аргумента. Это также отобразит на странице «Hello, World».
class App extends Component {
render() {
return (
<div>
<Helloworld helloprop="Hello, World" />
</div>
);
}
}
class Helloworld extends Component {
render() {
return (
<p>{this.props.helloprop}</p>
);
}
}
Быстрые обращения - Состояние
5. Мы также можем передавать значения реквизита из состояния компонента. Состояние - это доступная для чтения и записи информация для конкретного компонента, которая обеспечивает интерактивность в наших компонентах React. Наш компонент будет повторно визуализироваться при изменении состояния. Приведенный ниже фрагмент также отображает «Hello, World» на странице…
class App extends Component {
state = { hellostate: "Hello, World" } render() { return ( <div> <Helloworld helloprop={this.state.hellostate} /> </div> ); } } class Helloworld extends Component { render() { return ( <p>{this.props.helloprop}</p> ); } }
6.… И мы можем установить состояние непосредственно из props, по-прежнему без указания props в качестве параметра или использования метода жизненного цикла setState ().
class App extends Component {
state = { hellostate: "Hello, World" }
render() { return ( <div> <Helloworld helloprop={this.state.hellostate} /> </div> ); } } class Helloworld extends Component { state = { hellostatetwo: this.props.helloprop } render() { return ( <p>{this.state.hellostatetwo}</p> ); } }
Что дает? Все в порядке или мы что-то упускаем из виду?
Ответ, на который я остановился: может быть! И пока это нормально. Оказывается, в большинстве случаев все вышеперечисленное может быть приемлемым, но, как и в случае с большинством концепций, могут возникнуть ошибки в зависимости от использования. Благодаря этому вопросу из React Docs и этой ветке StackOverflow за некоторую ясность по этому поводу.
Из документации React:
Компоненты класса всегда должны вызывать базовый конструктор с
props
.
Когда вы передаете props
в this
, свойства назначаются this
, поэтому мы можем использовать значение this.props
внутри конструктора.
Очевидно, в сообществе до сих пор ведутся споры о намерениях этой спецификации. Некоторые причины, которые были предложены, включают:
- Подклассы
- Будущая совместимость
7. Это похоже на этот фрагмент ниже. Это интересно, потому что, как мы видели, реквизиты доступны без этого шага.
class HelloWorld extends React.Component
{
constructor(props) {
super(props);
this.state = {
hellostate: this.props.hello
};
}
//...
}
НО! Мы знаем, что не можем установить состояние напрямую, верно? Нам всегда нужно использовать setState()
? Неправильный!
Фактически, согласно документации, вам не следует называть setState()
в constructor()
. Вместо этого, если вашему компоненту необходимо использовать локальное состояние, присвойте начальное состояние this.state
непосредственно в конструкторе .
8. Хорошо, но даже если мы продолжим, как описано в последнем фрагменте кода, мы снова ошибаемся. Фактически, документы называют этот случай именно антипаттерном.
Избегайте копирования реквизита в состояние! Это распространенная ошибка:
constructor(props) {
super(props);
// Don't do this!
this.state = { color: props.color };
}
Здесь три проблемы:
- В этом нет необходимости: вы можете (и должны) использовать
this.props.color
непосредственно вместо того места, где вы планировали использоватьthis.state.color
. - Мы искажаем наш источник информации: мы всегда хотим поддерживать «единый источник правды» о данных, содержащихся в
this.props.color
. В этом случае это должны быть только данные, передаваемые в качестве свойств нашему компоненту, и они не должны изменяться. - Этот шаблон создает ошибки: обновления свойства
color
не отражаются в состоянии.
На первый взгляд, существует только один вариант использования для установки состояния непосредственно из реквизита: Намеренное игнорирование обновлений реквизита.
Это не кажется обычным явлением, поэтому будьте осторожны, прежде чем продолжить. Поскольку мы хотим разобраться в этом конкретном случае, имеет смысл переименовать опору в initialColor
или defaultColor
. Затем вы можете заставить компонент сбросить свое внутреннее состояние, изменив его key
, когда это необходимо.
Чтобы продолжить этот ход мыслей, ознакомьтесь с документами, а также с этим отличным сообщением в блоге Брайана Вона Вероятно, вам не нужно производное состояние.
Мысли? Дайте мне знать, как вы к этому подходите, в комментариях.
Похоже, что за этим следует внимательно следить в документации React, когда вы разрабатываете свой собственный проект. Удачи!
Привет, Кристи Бирн, Мелика Калбаси и Линдси Уолкер из Root Route.