Введение
react — действительно удивительный и элегантный фреймворк. Прежде чем приступить к проекту React, я работал над angular.Angular – это всеобъемлющий и огромный фреймворк. Когда он был изначально разработан, в нем есть все, и сложность очень высока. Поэтому использование angular для выполнения проектов в основном не требует других вспомогательные библиотеки.к сотрудничеству. Но реактивный проект совсем другой: если реактив только один, сложно разрабатывать требования. Потому что реакция отвечает только за рендеринг пользовательского интерфейса.
Вот шаблон для моей разработки реактивного проекта.Есть соответствующие примеры для нужд, возникающих в обычном процессе разработки.Стек технологий:react
+ react-router
+ react-redux
+ saga
+ reselector
+ webpack
+ ES6
+ Typescript
+ sass
.Нажмите здесь, чтобы посетить
Что вам нужно освоить, чтобы сделать реактивный проект
reactОдна функция используется для рендеринга пользовательского интерфейса,reduxуправлять данными,react-routerиспользуется для управления маршрутизацией,webpackиспользуется для настройки проекта,ES6сделать код более элегантным,redux-sagaИспользуется для обработки асинхронных запросов,reselectМеханизм кэширования используется для уменьшения нагрузки на рендеринг, вызванной изменениями состояния, и для взаимодействия создано некоторое промежуточное программное обеспечение.react-redux,react-router-redux,react-router-dom, препроцессорSassилиLessУхватитесь за него как можно сильнее.react
Как упоминалось ранее, реакция отвечает только за рендеринг пользовательского интерфейса.
Из V-дома
Самое ценное в React — это идея виртуального дома, вот удачная аналогия: подумайте о доме и JavaScript как о двух островах, соединенных мостом посередине, но на мосту есть платная станция, тем больше раз JavaScript посещает остров Дом. Чем больше, тем выше стоимость. Это процесс js, манипулирующий DOM. Возможно, мы часто слышим или видим, что работа с DOM как можно меньше требует высокой производительности. ноОткуда высокая стоимость эксплуатации DOM?, вот небольшое резюме:
От ввода uri до загрузки страницы — очень долгий процесс, начнем с разбора html. ① Разобрать HTML и начать строить дерево DOM; ② Разобрать CSS для создания дерева правил CSS; ③ Объединить дерево DOM и дерево правил CSS для создания дерева рендеринга; ④ Макет дерева рендеринга (Layout/reflow), который отвечает за размер и положение элементы в это время Расчет относится к процессу перекомпоновки в js; ⑤ Отрисовка дерева рендеринга (краска), отрисовка пикселей страницы относится к процессу перерисовки; ⑥ Браузер будет отправлять информацию о каждом слое на графический процессор (процессор изображения) и GPU будет синтезировать каждый слой (композит), отображаемый на экране. Это процесс инициализации рендеринга.После работы с DOM через js вызоветпереплавкаИ перерисовка, стоимость перекомпоновки очень высока.Перекомпоновка узла приведет к перекомпоновке родственных узлов и дочерних узлов, которые потребляют ресурсы графического процессора, поэтому говорят, что стоимость высока.
Мы вводим react из стоимости эксплуатации dom, он создает виртуальные dom и сохраняет их, а каждый раз при изменении состояния создает новый виртуальный узел для сравнения с предыдущим, чтобы рендерилась измененная часть. Весь процесс не получает и не управляет DOM, и только когда ожидается реальный рендеринг, реальный DOM будет манипулироваться, тем самым запуская рендеринг страницы.
Недостатки V-дома
ReactJS использует виртуальный механизм DOM, позволяющий разработчикам внешнего интерфейса предоставлять функцию рендеринга для каждого компонента. Функция рендеринга преобразует реквизиты и состояние в виртуальную DOM ReactJS, а затем инфраструктура ReactJS создает реальную DOM с той же структурой на основе виртуальной DOM, возвращаемой рендерингом.
Всякий раз, когда состояние изменяется, платформа ReactJS повторно вызывает функцию рендеринга, чтобы получить новый виртуальный DOM. Затем платформа сравнивает различия между последней созданной виртуальной моделью модели DOM и новой виртуальной моделью модели DOM и применяет различия к реальной модели модели DOM.
В этом есть два основных недостатка:
//每次 state 更改,render 函数都要生成完整的虚拟 DOM,哪怕 state 改动很小,
//render函数也会完整计算一遍。如果 render 函数很复杂,这个过程就会白白浪费很多计算资源。
//ReactJS 框架比较虚拟 DOM 差异的过程,既慢又容易出错。比如,你想要在某个 <ul> 列表的顶部插入一项 <li> ,
//那么 ReactJS 框架会误以为你修改了 <ul> 的每一项 <li>,然后在尾部插入了一个 <li>。
Это связано с тем, что новая и старая виртуальные модели DOM, полученные ReactJS, не зависят друг от друга, ReactJS не знает, что случилось с источником данных, и может только угадывать операцию, которую необходимо выполнить, на основе старой и новой виртуальных моделей DOM. Алгоритм автоматического угадывания является неточным и медленным. Разработчики внешнего интерфейса должны вручную указать ключевой атрибут, метод shouldComponentUpdate, метод componentDidUpdate или метод componentWillUpdate, чтобы помочь фреймворку ReactJS правильно угадать.
алгоритм сравнения
Где используется алгоритм сравнения реакции? Когда компонент будет обновлен, реакция создаст новое виртуальное дерево dom и сравнит его с ранее сохраненным деревом dom.Этот процесс сравнения использует алгоритм diff, поэтому он не используется при инициализации компонента. React делает предположение, что один и тот же узел имеет схожую структуру, а разные узлы имеют разную структуру. Исходя из этого предположения, выполняется послойное сравнение.Если соответствующие узлы оказываются разными, старый узел и все содержащиеся в нем дочерние узлы напрямую удаляются и заменяются новым узлом. Если это один и тот же узел, вносятся только изменения свойств.
Алгоритм diff для списков немного отличается, так как списки обычно имеют одинаковую структуру, при удалении, вставке и сортировке узлов списка общая работа одного узла намного лучше, чем замена по одному, поэтому при создании списка , вам нужно установить значение ключа, чтобы реакция могла различать, кто есть кто. Конечно, также можно не записывать значение ключа, но обычно это выдает предупреждение, информирующее нас о необходимости добавить значение ключа для повышения производительности реакции.
Для более глубокого понимания исходного кода diff см.Анализ исходного кода!
единый поток данных
составной
Компонент — это модуль представления с независимыми функциями.Самое большое преимущество React заключается в том, что функция разделена на компоненты и следует принципу удобства обслуживания интерфейса.
жизненный цикл компонента
5 функций ловушек, запускаемых при инициализации компонента
1.getDefaultProps()
Установите свойства по умолчанию, вы также можете использовать defaultProps, чтобы установить свойства компонента по умолчанию.
getDefaultProps эквивалентен static defaultProps = {} в ES6.
2.getInitialState()
При использовании синтаксиса класса es6 такой функции-ловушки нет, вы можете определить this.state непосредственно в конструкторе. This.props доступен в этот момент.
getInitialState эквивалентен this.state = {} конструктора в классе ES6.
Hook function 1 2 Будет работать только класс компонента, созданный методом React.createClass, а React.createClass официально заброшен Fb, поэтому я не буду здесь вдаваться в подробности.
3.componentWillMount()
Он вызывается только при инициализации компонента и не будет вызываться при обновлении компонента в будущем, вызывается только один раз за весь жизненный цикл, и состояние в это время может быть изменено.
4.render()
Здесь выполняются самые важные шаги реакции, создание виртуального дома, выполнение алгоритма сравнения и обновление дерева домов.
render() должна быть чистой функцией, определяющей возвращаемый результат на основе состояния и реквизитов без побочных эффектов, поэтому вызов setState в рендере неправильный, поскольку чистые функции не должны вызывать изменения состояния
5.componentDidMount()
Вызывается после рендеринга компонента, вы можете получить и управлять узлом DOM через this.getDOMNode(), который вызывается только один раз.
Префикс did указывает, что он вызывается после входа в состояние, такое как componentDidMount, где компонент обычно инициализируется для запроса данных.
Почему данные запроса должны вызываться в этой функции ловушки?
См. мое резюмеОтветы на некоторые проблемы, возникающие в реакции
5 функций ловушек, запускаемых при интерактивном обновлении компонентов
6.componentWillReceiveProps(nextProps)
Не вызывается при инициализации компонента, вызывается, когда компонент принимает новые реквизиты.
В процессе разработки в эту функцию ловушки обычно вносятся изменения.state
, Изменение состояния в этом методе не приведет к отображению состояния дважды, а объединит состояние.
7.shouldComponentUpdate(nextProps, nextState)
Очень важная часть оптимизации производительности реакции. Вызывается, когда компонент принимает новое состояние или реквизиты, мы можем установить, одинаковы ли два реквизита и состояние до и после сравнения, если они одинаковы, вернуть false, чтобы предотвратить обновление, потому что одно и то же состояние свойства определенно сгенерирует то же самое дерево DOM, поэтому нет необходимости создавать новое дерево DOM и сравнивать старое дерево DOM для алгоритма сравнения, что значительно экономит производительность, особенно когда структура DOM сложна. Однако при вызове this.forceUpdate этот шаг пропускается.
8.componentWillUpdate(nextProps, nextState)
Не вызывается при инициализации компонента, вызывается только при обновлении компонента.
Не вызывайте метод this.setState() в этой функции, это вызовет циклические вызовы.
9.render()
То же, что и выше для render(), создайте виртуальный дом, выполните алгоритм сравнения и обновите здесь дерево домов.
10.componentDidUpdate()
Он не вызывается при инициализации компонента, а вызывается после обновления компонента, и в это время можно получить узел dom.
Только после того, как componentDidUpdate сможет получить обновленныйthis.state
. Если вы хотите получить свойства компонента по умолчанию и назначить его состоянию, вы можете изменить его здесь, чтобы добиться эффекта в пользовательском интерфейсе.
Вызывается при выгрузке компонента
10.componentWillUnmount()
Вызывается, когда компонент собирается выгрузиться, в это время необходимо очистить некоторые прослушиватели событий и таймеры, и значение хранилища компонента также может быть соответственно очищено.
componentWillUnmount выполняет сброс всех соответствующих параметров. Вызов setState в этом методе не приведет к запуску рендеринга, поскольку все очереди обновлений и состояние обновления сбрасываются до нуля.
//数据清楚需要写在reducer里面
this.props.clearPointData();
[CLEAR_POINT_DATA]: (state, action: Action<any>) => {
return Object.assign({}, state, {
selectedReadingList: {},
knowledgePoint: {},
});
}
Из вышеизложенного видно, что в реакции есть в общей сложности 10 периодических функций (рендеринг повторяется один раз), эти 10 функций могут удовлетворить все наши потребности в операциях с компонентами, а правильное использование может повысить эффективность разработки и производительность компонентов.
react-router
Маршрутизатор — это компонент React, он не будет отображаться, это просто объект конфигурации, который создает внутренние правила маршрутизации и отображает соответствующие компоненты в соответствии с соответствующим адресом маршрутизации. Route связывает адреса маршрутизации и компоненты Route имеет функцию вложенности, указывающую отношение включения адресов маршрутизации, которое не связано напрямую с вложенностью между компонентами. Маршрут может передавать связанному компоненту 7 атрибутов: дочерние элементы, история, местоположение, параметры, маршрут, параметры маршрута, маршруты, каждый атрибут содержит информацию, связанную с маршрутизацией. Чаще всего используются дочерние элементы (компоненты, отличающиеся отношением включения маршрутов), местоположение (включая адреса, параметры, методы переключения адресов, ключевые значения и хэш-значения). React-router предоставляет тег Link, который является просто инкапсуляцией тега a. Стоит отметить, что переход по ссылке не является способом по умолчанию. React-router предотвращает поведение тега по умолчанию и использует pushState для изменить значение хэша. Процесс переключения страниц заключается в том, что при нажатии метки Link или кнопок «назад» и «вперед» сначала будет изменен URL-адрес.Маршрутизатор прослушивает изменение адреса и сопоставляет соответствующий компонент в соответствии с атрибутом пути маршрута. , изменяет значение состояния на соответствующий компонент и вызывает setState, запускает функцию рендеринга для повторного рендеринга dom.Когда страниц много, проект будет становиться все больше и больше. Особенно для одностраничных приложений начальная скорость рендеринга будет очень медленной. В это время ее нужно подгружать по требованию. Только при переключении на страницу будет соответствующая страница будет загружена.js файл. Метод реакции и веб-пакета для загрузки по требованию очень прост: компонент Route меняется на getComponent, компонент получается с помощью require.ensure, а в веб-пакете настраивается chunkFilename.
const chooseProducts = (location, cb) => {
require.ensure([], require => {
cb(null, require('../Component/chooseProducts').default)
},'chooseProducts')
}
const helpCenter = (location, cb) => {
require.ensure([], require => {
cb(null, require('../Component/helpCenter').default)
},'helpCenter')
}
const saleRecord = (location, cb) => {
require.ensure([], require => {
cb(null, require('../Component/saleRecord').default)
},'saleRecord')
}
const RouteConfig = (
<Router history={history}>
<Route path="/" component={Roots}>
<IndexRoute component={index} />//首页
<Route path="index" component={index} />
<Route path="helpCenter" getComponent={helpCenter} />//帮助中心
<Route path="saleRecord" getComponent={saleRecord} />//销售记录
<Redirect from='*' to='/' />
</Route>
</Router>
);
react-router-redux
Поддерживайте синхронизацию маршрутов с состоянием приложения. Используйте redux для управления состоянием приложения и router для управления маршрутизацией. Эти две библиотеки не могут работать вместе. Библиотека react-router-redux может координировать две библиотеки.
react-router-dom
...
redux
связь между компонентами
React продвигает односторонний поток данных, который передает данные сверху вниз, но связь между компонентами, которые находятся снизу вверх или не участвуют в потоке данных, усложнится. Есть много способов решить проблему связи.Если это только отношения родитель-потомок, родитель может передать функцию обратного вызова в качестве атрибута дочернему элементу, и дочерний элемент может напрямую вызвать функцию для связи с родителем.
Иерархия компонентов глубоко вложена, и контекст getChildContext может использоваться для передачи информации, так что к дочерним элементам любого уровня можно получить прямой доступ через this.context без необходимости передачи функций вниз.
Между компонентами родственного отношения нет прямой связи, и они могут использовать только вышестоящего уровня того же уровня в качестве точки транзита. И если одноуровневые компоненты являются компонентами самого высокого уровня, для того, чтобы они могли взаимодействовать, на внешнем их уровне должен быть установлен слой компонентов.Этот внешний слой компонентов играет роль сохранения данных и передачи информации, которая на самом деле то, что делает редукс.
Информация между компонентами также может передаваться через глобальные события. Разные страницы могут передавать данные через параметры, а следующую страницу можно получить с помощью location.param. На самом деле, сам react очень прост, сложность заключается в том, как элегантно и эффективно добиться обмена данными между компонентами.
redux
Во-первых, редукс не нужен, его функция эквивалентна добавлению другого компонента поверх компонента верхнего уровня, его функция заключается в выполнении логических операций, хранении данных и реализации связи между компонентами, особенно компонентами верхнего уровня. Если связи между компонентами не так много и логика не сложная, то просто рендерит вид, в это время можно использовать callback и контекст, нет необходимости использовать redux, что повлияет на скорость разработки. Но если компоненты обмениваются данными очень часто, а логика очень сложная, преимущества редукции особенно очевидны. Когда я впервые работал над реактивным проектом, я не использовал редукс, и вся логика была реализована внутри компонента, тогда, чтобы реализовать корзину со сложной логикой, я фактически написал более 800 строк кода. Я не знаю, что написать, настолько трогательна картина.
Давайте кратко поговорим о том, как редукс и реакция работают вместе. React-redux предоставляет двух хороших друзей, connect и Provider, один из которых связывает компонент с redux, а другой передает хранилище компоненту. Компонент отправляет действие через диспетчеризацию, а хранилище вызывает соответствующий редьюсер в соответствии с атрибутом типа действия и передает состояние и действие. Редьюсер обрабатывает состояние и возвращает новое состояние для помещения в хранилище. для изменений в магазине и вызывает setState для обновления компонента. , пропсы компонента изменятся соответственно.
Процесс выглядит следующим образом:
Стоит отметить, что connect, Provider, mapStateToProps и mapDispatchToProps предоставляются react-redux.Сам Redux не имеет ничего общего с react.Это просто центр обработки данных и не имеет никакой связи с react.React-redux их соединяет вместе. .
Далее подробно разберем, как реализованы redux и react-redux.
Первая картинка
Явно сложнее, чем первая, на самом деле две картинки говорят об одном и том же. Медленно проанализируйте сверху вниз:
Давайте сначала поговорим о редуксе:
Redux в основном состоит из трех частей: хранилища, редуктора и действия.
store — это объект, который имеет четыре основных метода:
1. отправка:
Для распределения действия ---- В createStore промежуточное программное обеспечение промежуточного слоя может использоваться для преобразования отправки. Например, когда действие передается в отправку, редуктор будет запущен немедленно. Иногда мы не хотим, чтобы он запускался немедленно, но ждем асинхронная операция для завершения. Запущено. В настоящее время для преобразования отправки используется redux-thunk. Раньше можно было передать только один объект. После завершения преобразования можно передать функцию. В этой функции мы вручную отправить объект действия. Этот процесс управляем и реализован. Асинхронный.
2. подписаться:
Мониторинг изменений состояния----Эта функция зарегистрирует прослушиватель для отслеживания изменений состояния, когда хранилище вызывает диспетчеризацию.Когда нам нужно знать, изменяется ли состояние, мы можем вызвать его.Он возвращает функцию, и вызов возвращаемой функции может отменить монитор. let unsubscribe = store.subscribe(() => {console.log('состояние изменилось')})
3. получить состояние:
Получить состояние в хранилище ---- Когда мы используем действие для запуска редуктора для изменения состояния, нам нужно получить данные в новом состоянии, в конце концов, данные — это то, что нам нужно. getState в основном используется в двух случаях. Во-первых, после того, как диспетчер получает действие, хранилище должно использовать его для получения данных в состоянии и передать данные редюсеру. Этот процесс выполняется автоматически. Во-вторых, когда мы используем подписку. Прослушав изменение состояния, вызовите его, чтобы получить новые данные о состоянии.Если этот шаг выполнен, это означает, что мы преуспели.
4. заменить Редуктор:
Замените редюсер и измените логику изменения состояния.
action:
Действие — это объект, для которого требуется атрибут типа и могут быть переданы некоторые данные. Действия можно создавать с помощью actionCreator. диспетчеризация должна отправить объект действия.
reducer:
Редьюсер — это функция, которая принимает состояние и действие и возвращает новое состояние в зависимости от типа действия. Согласно бизнес-логике его можно разбить на множество редьюсеров, а затем объединить их через combReducers.В дереве состояний много объектов, каждому объекту состояния соответствует редюсер, а имя объекта состояния можно определить при объединении .
что-то вроде этого:
const reducer = combineReducers({
a: doSomethingWithA,
b: processB,
c: c
})
combineReducers:
По сути это тоже редьюсер.Он принимает состояние и действие целиком, а затем разбивает все состояние и отправляет на обработку соответствующему редьюсеру.Все редюсеры получат одно и то же действие, но будут оцениваться по Тип действия.Есть это Тип будет обработан и будет возвращено новое состояние, если нет, то будет возвращено значение по умолчанию, а затем эти разбросанные состояния будут объединены вместе, чтобы вернуть новое дерево состояний.
Далее давайте проанализируем процесс в целом. Сначала вызовите store.dispatch, чтобы передать действие в качестве параметра. В то же время используйте getState для получения текущего состояния дерева состояний и зарегистрируйте прослушиватель подписки для отслеживания изменения состояния. Затем вызовите combReducers и передать полученное состояние и действие. . combReducers будет передавать входящее состояние и действие всем редукторам и возвращать новое состояние в соответствии с типом действия, запуская обновление дерева состояний.Мы вызываем subscribe для отслеживания изменения состояния и используем getState для получения данных о новом состоянии.
Состояние редукции и состояние реакции не имеют абсолютно ничего общего друг с другом, за исключением того, что имена одинаковы.
Основные функции redux проанализированы выше, так что же делает react-redux?
react-redux
Если использовать только редукцию, поток выглядит следующим образом:
component --> dispatch(action) --> reducer --> subscribe --> getState --> component
После использования react-redux процесс выглядит так:
component --> actionCreator(data) --> reducer --> component
Три функции хранилища: диспетчеризация, подписка и getState не требуют написания вручную. react-redux делает это за нас и предоставляет двух хороших друзей, Provider и connect.
ProviderЭто компонент, который принимает хранилище в качестве реквизита, а затем передает его вниз через контекст, так что любой компонент в реакции может получить хранилище через контекст. Это означает, что мы можем использовать диспетчеризацию (действие) в любом компоненте, чтобы инициировать редуктор для изменения состояния, использовать подписку для отслеживания изменения состояния, а затем использовать getState для получения измененного значения. Но это не рекомендуется, это сделает поток данных хаотичным, чрезмерная связанность также повлияет на повторное использование компонентов, и это будет более проблематично в обслуживании.
connect --connect(mapStateToProps, mapDispatchToProps, mergeProps, options)- это функция, которая принимает четыре параметра и возвращает функцию --wrapWithConnect, wrapWithConnect принимает компонент в качестве параметра wrapWithConnect(component), который определяет новый компонент Connect (компонент-контейнер) и входящий компонент (компонент пользовательского интерфейса) в качестве подкомпонента Connect а потом обратно.
Таким образом, его полное написание выглядит так: connect(mapStateToProps, mapDispatchToProps, mergeProps, options)(component)
mapStateToProps (состояние, [ownProps]):
mapStateToProps принимает два параметра, состояние хранилища и пользовательские реквизиты, и возвращает новый объект, который будет передан компоненту пользовательского интерфейса как часть реквизита. Мы можем настроить возврат объекта в соответствии с данными, требуемыми компонентом. Изменения в ownProps также запускают mapStateToProps.
function mapStateToProps(state) {
return { todos: state.todos };
}
mapDispatchToProps (отправка, [ownProps]):
Если mapDispatchToProps является объектом, он будет привязан к хранилищу и передан компоненту пользовательского интерфейса как часть реквизита. Если это функция, она принимает два параметра, bindActionCreators свяжет действие, отправит и вернет объект, который будет передан компоненту пользовательского интерфейса вместе с ownProps как часть реквизита. Таким образом, независимо от того, является ли mapDispatchToProps объектом или функцией, в конечном итоге он вернет объект.Если это функция, значение ключа этого объекта можно настроить.
function mapDispatchToProps(dispatch) {
return {
todoActions: bindActionCreators(todoActionCreators, dispatch),
counterActions: bindActionCreators(counterActionCreators, dispatch)
};
}
Свойства объектов, возвращаемые mapDispatchToProps, на самом деле являются actionCreators.Поскольку они привязаны к диспетчеризации, действия будут отправлены немедленно при вызове actionCreator без ручной диспетчеризации. Изменения в ownProps также запускают mapDispatchToProps.
mergeProps (stateProps, dispatchProps, ownProps):
Объедините объекты, возвращаемые функциями mapStateToProps() и mapDispatchToProps(), и реквизиты самого компонента в новые реквизиты и передайте их в компонент. Возвращает результат Object.assign({}, ownProps, stateProps, dispatchProps) по умолчанию.
опции:
pure = true означает, что компонент контейнера Connect будет выполнять поверхностное сравнение состояния хранилища и ownProps в shouldComponentUpdate, чтобы определить, произошли ли изменения, и оптимизировать производительность. false, чтобы не сравнивать.
На самом деле функция подключения ничего не делает, большая часть логики реализована в функции wrapWithConnect, которую она возвращает, а точнее в компоненте Connect, определенном в wrapWithConnect.
Ниже приведен полный процесс реакции --> редукции --> реакции:
1. Компонент Provider принимает хранилище избыточности в качестве реквизита, а затем передает его вниз через контекст.
2. Функция подключения привяжет объект mapDispatchToProps к хранилищу при его инициализации.Если mapDispatchToProps является функцией, после того, как компонент Connect получит хранилище, привяжите его через bindActionCreators в соответствии с входящим store.dispatch и действием, а затем привяжите объект возвращаемый объект.Установив значение store, функция подключения вернет функцию wrapWithConnect, а функция wrapWithConnect будет вызвана и передана в компонент пользовательского интерфейса, wrapWithConnect использует класс Connect extends Component для определения компонента Connect, а входящий компонент пользовательского интерфейса является подкомпонентом Connect, а затем Connect Компонент получит хранилище через контекст и получит полный объект состояния через store.getState, передаст состояние в mapStateToProps и вернет объект stateProps, объект mapDispatchToProps или функция mapDispatchToProps вернет объект dispatchProps, stateProps, dispatchProps и реквизиты компонента Connect проходят через Object .assign(), или mergeProps объединяется с реквизитами и передается компоненту пользовательского интерфейса. Затем вызовите store.subscribe в ComponentDidMount и зарегистрируйте функцию обратного вызова handleChange для отслеживания изменений состояния.
3.В это время компонент ui может найти в пропсе actionCreator.При вызове actionCreator автоматически будет вызвана диспетчеризация.В диспетчере будет вызван getState для получения всего состояния.При этом, слушатель будет зарегистрирован для отслеживания изменений состояния, а состояние и действие будут получены хранилищем.Передайте его в combReducers, CombineReducers передаст состояние субредукторам в соответствии со значением ключа состояния, и передать действие всем подчиненным редюсерам, и редукторы будут выполняться по очереди, чтобы судить о действии. Если нет, вернитесь к умолчанию. combReducers снова объединяет отдельные состояния, возвращаемые дочерними редюсерами, в новое полное состояние. В этот момент состояние изменилось. Dispatch вызовет все зарегистрированные функции слушателя после того, как состояние вернет новое значение, включая функцию handleChange. Функция handleChange сначала вызывает getState, чтобы получить новое значение состояния, и сравнивает старое и новое состояния. Если они совпадают, выполняется прямой возврат. Если они разные, вызов mapStateToProps получает stateProps и поверхностно сравнивает старый и новый stateProps.Если они совпадают, возвращаемся сразу в конец, и никакие последующие операции не выполняются. Если это не то же самое, вызовите this.setState(), чтобы инициировать обновление компонента Connect, передать компонент пользовательского интерфейса и вызвать обновление компонента пользовательского интерфейса.В это время компонент пользовательского интерфейса получает новые реквизиты, а процесс реакции --> редукс --> реакция заканчивается.
Вышеупомянутое немного сложно, и упрощенная версия процесса:1. Компонент Provider принимает хранилище избыточности в качестве реквизита, а затем передает его вниз через контекст.
2. Функция подключения получает хранилище от провайдера, а затем принимает три параметра mapStateToProps, mapDispatchToProps и компонент и передает состояние и actionCreator компоненту в качестве реквизита.В это время компонент может вызвать функцию actionCreator для запуска функция редуктора для возврата нового состояния, соединение прослушивает изменения состояния и вызывает setState для обновления компонента и передачи нового состояния в компонент.
connect можно написать очень лаконично.mapStateToProps и mapDispatchToProps — это просто входящие callback-функции.connect функция будет вызывать их при необходимости.имена не фиксированы или даже не надо писать.
Упрощенная версия:
connect(state => state, action)(Component);
redux-saga
Быть обновленным. . .
reselect
Самая затратная операция в React — это цикл рендеринга: когда компонент обнаруживает изменение на входе, запускается цикл рендеринга.Когда мы впервые запустили программу React, мы не беспокоились о стоимости цикла рендеринга, но когда наш пользовательский интерфейс усложняется, нам нужно принять это во внимание. React предоставляет некоторые инструменты, которые позволяют нам перехватить цикл рендеринга, если Рендеринг кажется ненужным, мы можем использовать инструменты для предотвращения повторного рендеринга.Для этого нам нужно ввести событие жизненного цикла componentShouldUpdate, которое возвращает логическое значение, чтобы уведомить компонент о необходимости его обновления.Это основано на PureRenderMixin , Он сравнивает входные реквизиты и состояние с предыдущими реквизитами и состоянием и возвращает false, если они равны.
К сожалению, это все.
Reselect — это библиотека, используемая для запоминания селекторов. Мы определяем селекторы как функции для извлечения части состояния Redux. Используя возможности мемоизации, мы можем организовать ненужный повторный рендеринг и вычисление производных данных, тем самым ускоряя наше приложение.
Проблема, которую необходимо решить с помощью промежуточного программного обеспечения Reselect:在组件交互操作的时候,state发生变化的时候如何减少渲染的压力.在Reselect中间中使用了缓存机制
«селектор» — это простая библиотека Redux.
- Selector может вычислять производные данные, позволяя Redux хранить как можно меньше состояний.
- Селектор более эффективен, и процесс расчета происходит только при изменении параметра.
- Селекторы составные, их можно передавать в качестве входных данных другим селекторам.
Ссылаться на
-Улучшите производительность программ React и Redux с помощью Reselect
ES6
В реактивном проекте везде можно увидеть ES6/7/8, поэтому ES6 тоже нужно освоить.Поскольку контента слишком много, я кратко суммирую некоторые часто используемые приемы. Для конкретной справкиВведение учителя Руан Ифэн в ES6.На самом деле, по сравнению с ES5, ES6 добавила много чего, в том числе и часто используемые: используйте let const, чтобы полностью отказаться от var, импорт и экспорт шаблонов (import, export), расширение строки (``, ${}); Расширение объекта (присвоение структуры, новые API, такие как assgin(), keys(), is() и т. д.; расширение массива (присвоение структуры, from(), of(), findIndex(), find() и т. д.) ;Расширение функций (параметры функций могут задавать значения по умолчанию, стрелочные функции, объекты без аргументов и т. д.); обычно используются для обхода (для of, forEach, for in, map и т. д.); используются для решения асинхронных задач (функция-генератор, обещание, асинхронная функция /await и т. д.); ключевые слова class и extends и т. д.
Хотя многие навыки ES6 также могут быть реализованы с помощью ES5, ES6 значительно повышает эффективность разработки, а код становится более элегантным.Кроме того, различные инструменты упаковки могут конвертировать ES6 в ES5, подходящую для низкоуровневых браузеров, поэтому его рекомендуется использовать всем.
webpack
Обратитесь к официальному сайту webpack
Sass or Less
С постоянным развитием фронтенда увеличивается и сложность страниц сайта, нативный CSS лишил разработчиков возможности делать то, что они хотят, а препроцессор дает нам «суперсилу».Говоря о препроцессорах CSS: зачем использовать препроцессор?
Sass
Less
Обратитесь к меньшему синтаксису
===================================end==================================
React Prepare
Напоследок прилагаются соответствующие ссылки на стек технологий реагирования, надеюсь, это будет всем полезно!
react
React вводный пример учебника
Серия учебных пособий по стеку технологий React
реактивный компонент
Три способа создания компонентов в React и их отличия
Важность разделения компонентов реакции с точки зрения производительности
реагировать на статьи о производительности
Резюме по оптимизации производительности React
Современная веб-разработка — React
9 вещей, которые должны знать новички в React.js
react router
Руководство по React Router
redux
Вводное руководство по Redux (1): основное использование
Вводное руководство по Redux (2): промежуточное ПО и асинхронные операции
Вводное руководство по Redux (3): использование React-Redux
Китайская документация Redux
Английская документация Redux
Основные концепции Redux
Практический опыт React: подробное объяснение метода соединения react-redux
redux-saga/redux-thunk
документация саги на китайском языке
Давайте поговорим о редукционной саге об асинхронном потоке редукции.
Практическое руководство по Redux-Saga
Reselect
Others
Начало работы с архитектурой Flux
Immutable
dom diff
Значение и использование функции генератора