В чем разница между использованием конструктора и getInitialState в React/React Native?
Я видел, что оба используются взаимозаменяемо.
Каковы основные варианты использования для обоих? Есть ли преимущества/недостатки? Является ли практика лучшей?
Ответы
Ответ 1
Эти два подхода не являются взаимозаменяемыми. Вы должны инициализировать состояние в конструкторе при использовании классов ES6 и определить метод getInitialState
при использовании React.createClass
.
См. Официальный документ React по теме ES6.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { /* initial state */ };
}
}
эквивалентно
var MyComponent = React.createClass({
getInitialState() {
return { /* initial state */ };
},
});
Ответ 2
Разница между constructor
и getInitialState
- это разница между ES6 и ES5.
getInitialState
используется с React.createClass
и
constructor
используется с React.Component
.
Следовательно, вопрос сводится к преимуществам/недостаткам использования ES6 или ES5.
Давайте посмотрим на разницу в коде
ES5
var TodoApp = React.createClass({
propTypes: {
title: PropTypes.string.isRequired
},
getInitialState () {
return {
items: []
};
}
});
ES6
class TodoApp extends React.Component {
constructor () {
super()
this.state = {
items: []
}
}
};
Существует интересная тема Reddit.
Сообщество React приближается к ES6. Также это считается лучшей практикой.
Есть некоторые различия между React.createClass
и React.Component
. Например, как обрабатывается this
в этих случаях. Подробнее о таких различиях читайте в этом посте и в фейсбуке об автосвязывании
constructor
также может быть использован для обработки таких ситуаций. Чтобы привязать методы к экземпляру компонента, его можно предварительно связать в constructor
. Этот - хороший материал для таких крутых вещей.
Еще несколько хороших материалов о лучших практиках
Лучшие практики для состояния компонентов в React.js
Преобразование проекта React из ES5 в ES6
Обновление: 9 апреля 2019 года:
С новыми изменениями в API класса Javascript вам не нужен конструктор.
Вы могли бы сделать
class TodoApp extends React.Component {
this.state = {items: []}
};
Это все равно будет перенесено в формат конструктора, но вам не придется об этом беспокоиться. Вы можете использовать этот формат, который является более читабельным.
с реактивными крючками
Начиная с версии React 16.8, появился новый API Called hooks.
Теперь вам даже не нужен компонент класса, чтобы иметь состояние. Это даже можно сделать в функциональном компоненте.
import React, { useState } from 'react';
function TodoApp () {
const items = useState([]);
Обратите внимание, что начальное состояние передается в качестве аргумента useState
; useState([])
Подробнее о реакционных крючках читайте в официальных документах.
Ответ 3
Хорошо, большая разница начинается с того, откуда они идут, поэтому constructor
является конструктором вашего класса в JavaScript, с другой стороны, getInitialState
является частью lifecycle
React
.
constructor
, где ваш класс инициализируется...
Конструктор
Метод конструктора является специальным методом для создания и инициализации объекта, созданного с помощью класса. В классе может быть только один специальный метод с именем "конструктор". Синтаксическая ошибка будет выбрана, если класс содержит более одного вхождения метода конструктора.
Конструктор может использовать ключевое слово super для вызова конструктора родительского класса.
В документе React v16 они не упомянули никаких предпочтений, но вам нужно getInitialState
если вы используете createReactClass()
...
Установка начального состояния
В классах ES6 вы можете определить начальное состояние, назначив this.state в конструкторе:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: props.initialCount};
}
// ...
}
С createReactClass() вы должны предоставить отдельный метод getInitialState, который возвращает начальное состояние:
var Counter = createReactClass({
getInitialState: function() {
return {count: this.props.initialCount};
},
// ...
});
Посетите здесь дополнительную информацию.
Также было создано изображение ниже, чтобы показать несколько жизненных циклов React Compoenents:
Ответ 4
Если вы пишете класс React-Native с ES6, будет следовать следующий формат. Он включает методы жизненного цикла RN для класса, производящего сетевые вызовы.
import React, {Component} from 'react';
import {
AppRegistry, StyleSheet, View, Text, Image
ToastAndroid
} from 'react-native';
import * as Progress from 'react-native-progress';
export default class RNClass extends Component{
constructor(props){
super(props);
this.state= {
uri: this.props.uri,
loading:false
}
}
renderLoadingView(){
return(
<View style={{justifyContent:'center',alignItems:'center',flex:1}}>
<Progress.Circle size={30} indeterminate={true} />
<Text>
Loading Data...
</Text>
</View>
);
}
renderLoadedView(){
return(
<View>
</View>
);
}
fetchData(){
fetch(this.state.uri)
.then((response) => response.json())
.then((result)=>{
})
.done();
this.setState({
loading:true
});
this.renderLoadedView();
}
componentDidMount(){
this.fetchData();
}
render(){
if(!this.state.loading){
return(
this.renderLoadingView()
);
}
else{
return(
this.renderLoadedView()
);
}
}
}
var style = StyleSheet.create({
});
Ответ 5
В наши дни нам не нужно вызывать конструктор внутри компонента - мы можем напрямую вызывать state={something:""}
, в противном случае ранее сначала мы должны объявить конструктор с помощью super()
чтобы потом наследовать все от класса React.Component
внутри конструктора мы инициализируем наше состояние.
Если используется React.createClass
определите состояние инициализации с getInitialState
метода getInitialState
.