Функциональные точки после React16 последовательно добавляются итеративно в нескольких версиях.Объяснение этой статьи основано на
16.6.0
версия Цель этой статьи - представить новые или измененные места в версии после React16, поэтому для функций версии до React16 эта статья расценивается как полное понимание вами, поэтому я не буду вдаваться в подробности.
Обзор обновлений
Обзор обновлений React v16.0 ~ React v16.6 (задействованы только некоторые распространенные API):
- React v16.0
-
render
Поддерживает возврат массивов и строк - Поддержка пользовательских свойств DOM
- Уменьшить размер файла
- React v16.3
createContext
createRef
- Обновления функций жизненного цикла
- React v16.4
возобновитьgetDerivedStateFromProps
- React v16.6
memo
lazy
- Suspense
static contextType
static getDerivedStateFromError
- Реагировать v16.7 (~ 1 кв. 2019 г.)
Hooks
Далее мы объясним точки обновления с большим влиянием и более высокой частотой использования один за другим.
PureComponent для чистых функций
Мы знаем, что оптимизация производительности компонентов React,shouldComponentUpdate
Функции важны, поэтому ReactReact.Component
добавлено на основанииReact.PureComponent
, но для написания чистой функции неклассовых классов такую удобную обработку добавить нельзя.
Для этой проблемы React16.6 добавилReact.memo
Эта компонента высокого порядка
Общее использование:
const C = React.memo(props => {
// xxx
})
React.memo
Реализация похожа наReact.PureComponent
, поэтому он внутренне выполняет поверхностное сравнение объектов.React.memo
Позволяет настроить метод сравнения следующим образом:
// 函数的返回值为 true 时则更新组件,反之则不更新
const equalMethod = (prevProps, nextProps): boolean => {
// 定义你的比较逻辑
}
const C = React.memo(props => {
// xxx
}, equalMethod)
Как выглядит новая функция жизненного цикла
Жизненный цикл React делится на три этапа: монтирование, обновление и выгрузка.После React16 есть еще одно исключение.Давайте посмотрим.
[Обновлены картинки, отдельное спасибо @wuzhengyan2015 за исправление]устанавливать
Порядок выполнения жизненного цикла
constructor
static getDerivedStateFromProps
render
componentDidMount
render
а такжеcomponentDidMount
Никаких изменений по сравнению с тем, что было до React16. Для процесса монтажа давайте сосредоточимся наconstructor
,componentWillMount
а такжеstatic getDerivedStateFromProps
.
constructor
- инициализировать состояние
Примечание: следует избегатьprops
Датьstate
задание, чтобыstate
Можно упомянуть инициализациюconstructor
внешнее лечение
constructor(props) {
super(props);
this.state = {
x: 1,
// y: props.y, // 避免这样做,后面我们会讲应该怎样处理
}
}
- связать это с методом
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
Тем не менее, две вышеуказанные вещи ставятсяconstructor
Внешняя обработка будет проще, а именно:
class C extends React.Component {
state = {
x: 1
}
handleClick = (e) => {
// xxx
}
}
Поэтому React16 будет использоваться позжеconstructor
сцены будут уменьшены.
componentWillMount
можно увидеть,componentWillMount
Его "убрали" в React16 (это на самом деле проблематично, т.к. React на самом деле не удаляет функцию жизненного цикла, а лишь предупреждает разработчиков о том, что эта функция будет устаревать в будущих версиях), тогда возникает проблема Теперь, что нужно сделать в этой жизненный цикл, где это должно быть сделано сейчас?
Сначала задайте себе вопрос, что есть в этом жизненном цикле? Ответ заключается в том, что большую часть времени нужно выполнять запросы AJAX, а затем выполнятьsetState
Перерендерить.
Однако вcomponentWillMount
Делать здесь AJAX-запросы действительно неразумно, потому что для изоморфных проектовcomponentWillMount
будет называться.
Кто-то еще будет инициализировать здесьstate
,оstate
Для инициализации обратитесь к разделу выше.
В итоге,componentWillMount
На самом деле, это не играет никакой роли: если ваша спецификация кода будет удалена, это никак не повлияет на текущий проект.
static getDerivedStateFromProps
Как мы упоминали выше, нам следует избегать использованияprops
Датьstate
Присваивание, но мы делали это до React 16. Теперь, если мы не разрешаем эту операцию, где мы должны иметь дело с этой логикой? Ответ, данный React16,static getDerivedStateFromProps
.
Когда компонент смонтирован, статический метод будетrender
перед выполнением; при обновлении компонента статический метод будет выполняться вshouldComponentUpdate
перед казнью.
class C extends React.Component {
state = {
y: 0
}
static getDerivedStateFromProps(props, state): State {
if(props.y !== state.y) {
return {
y: props.y
};
}
}
}
getDerivedStateFromProps
Возвращаемое значение будет такимsetState
Параметр, если он возвращает null, состояние не будет обновлено, и значение, отличное от object или null, не может быть возвращено, иначе будет выдано предупреждение.
getDerivedStateFromProps
Это статический метод и не может получить экземплярthis
, поэтому разработчики должны проектировать эту функцию как чистую функцию.
Итак, вы нашлиcomponentWillReceiveProps
Это бесполезно? Да, React16 тоже "удалил" его (это на самом деле проблематично, т.к. react на самом деле не удаляет функцию жизненного цикла, а лишь предупреждает разработчиков, что эта функция будет устаревать в будущих версиях, рекомендуется использовать более качественнуюgetSnapshotBeforeUpdate
илиgetDerivedStateFromProps
)
возобновить
Порядок выполнения функций жизненного цикла
static getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
static getDerivedStateFromProps
Он был представлен ранее, и несколько других функций жизненного цикла в основном такие же, как и до React16, так что вот основное введение.getSnapshotBeforeUpdate
.
getSnapshotBeforeUpdate
Вызывается до того, как React обновит DOM, на данный моментstate
обновлено;
возвращаемое значение какcomponentDidUpdate
Третий параметр;
обычно используется для полученияrender
предыдущие данные DOM
грамматика:
class C extends React.Component {
getSnapshotBeforeUpdate (prevProps, prevState): Snapshot {
}
componentDidUpdate(prevProps, prevState, snapshot) {
// snapshot 是从 getSnapshotBeforeUpdate 的返回值,默认是 null
}
}
getSnapshotBeforeUpdate
Сценарий использования обычно заключается в получении положения полосы прокрутки до обновления компонента.
удалить
componentWillUnmount
Никаких изменений по сравнению с предыдущим.
аномальный
componentDidCatch
Эта функция является новой в React16 и используется для перехвата исключений в дереве компонентов, еслиrender()
Если функция выдает ошибку, функция будет запущена. может следоватьtry catch
чтобы понять и использовать, где могут возникнуть ошибки, используйте упакованные включаетcomponentDidCatch
Компоненты жизненного цикла оборачивают компоненты, которые могут пойти не так.
class PotentialError extends React.Component {
state = {
error: false,
}
componentDidCatch(error, info) {
console.error(info);
this.setState({
error
});
}
render() {
if (this.state.error) {
return <h1>出错了,请打卡控制台查看详细错误!</h1>;
}
return this.props.children;
}
}
Такие как:
const Demo = () => (
<PotentialError>
<div>{{a: 1}}</div>
</PotentialError>
)
так,Demo
Даже если компонент напрямую использует объект как подкомпонент, он не сообщит об ошибке, т.к.PotentialError
получено.
Полная демонстрация нового жизненного цикла
Посмотрите, как это выглядит в новой одежде нового жизненного цикла
import React from 'react'
export default class MyComponent extends React.Component {
constructor(props) {
super(props);
// 初始化state方式(1)
this.state = {
}
}
static defaultProps = {
}
// 初始化state方式(2)
state = {
}
static getDerivedStateFromProps(props, state) {
return state
}
componentDidCatch(error, info) {
}
render() {
}
componentDidMount() {
}
shouldComponentUpdate(nextProps, nextState) {
}
getSnapshotBeforeUpdate(prevProps, prevState) {
}
componentDidUpdate(prevProps, prevState, snapshot) {
}
componentWillUnmount() {
}
}
Suspense
Hooks
time slicing
【Продолжение следует】