Рубрики
Без рубрики

Строительство Калькулятор температуры батареи Tesla с реакцией (часть 2: Redux версия)

Мэтью Чои Строительство Калькулятор батареи Tesla Calculator с реакцией (часть 2: Redux Version) В этом руководстве является вторая часть вторых калькулятора диаметра аккумулятора Tesla с реакцией. В части 1, после построения проекта через Create-React-App, мы реализовали каждый компонент, подведев UI. Нам удалось

Автор оригинала: FreeCodeCamp Community Member.

Мэтью Чой

В этом руководстве является вторая часть сооружения калькулятора температуры батареи Tesla с реакцией.

В части 1, после построения проекта через Create-React-App, мы реализовали каждый компонент, подведев UI. Мы управляли государством и событием, используя местные государства и реквизиты и завершили все приложение.

Если вы еще этого еще не прочитали, обязательно проверить часть 1, которая фокусируется на реакции, здесь :

Строительство Калькулятор температуры батареи Tesla с реакцией (часть 1) В этой серии статей я буду проходить вас через процесс создания калькулятора линейки батареи Tesla с реакцией … medium.freecodeCamp.com.

В этом взносе мы представим Redux, решение государственного управления, чтобы увидеть, как мы можем преобразовать наше приложение в приложение, которое управляет состоянием приложения с Redux.

Это окончательное изображение нашего применения в части 2:

? Проверьте часть 2 л Demo Demo.

Прежде чем мы посмотрим на то, что redux, давайте посмотрим, почему нам нужно использовать Redux для решения проблем.

1. Какую проблему мы решаем?

Redux становится тем фактоном способом построить реагированные приложения. Но должен быть использован Redux во всех приложениях React? По крайней мере, не все приложения понадобится амбициозное решение государственного управления с самого начала.

Сегодняшние тренды развития в первом классе являются Компонент на основе Отказ Компоненты могут иметь состояние данных и состояние интерфейса пользовательского интерфейса, а состояние, которое им нужно управлять, становится все более сложнее, поскольку ваше приложение растет.

Государственное управление Решения появились для решения следующих проблем, и Redux становится популярным как стандарт между другими решениями.

  • Компоненты обмениваются государством
  • Состояние должно быть доступно из любого места
  • компоненты должны мутировать государство
  • Компоненты должны мутировать состояния других компонентов

Redux – это Государственная библиотека управления , который является инструментом, который позволяет вам где-то хранить состояние нашего приложения, мутировать государство и получить обновленное состояние.

Другими словами, с redux у нас есть одно место, где мы можем обратиться к состоянию, изменить состояние и получить обновленное состояние.

Redux был написан с учетом реагирования, но это также Framework-agnostic И даже можно использовать с угловыми или jQuery приложениями.

2. Поток данных в Redux

Как вы видели в части 1, в реакции данные передаются через компонент с использованием реквизит. Это называется Однонаправленные данные поток это течет от родителя к ребенку.

Благодаря этим характеристикам связь между компонентами, отличными от родителей-детей, неясно.

Реагистрация не рекомендуется прямым Компонент к компоненту связь, как показано выше. Есть рекомендуемый путь для этого в реакции, но вы должны реализовать его самостоятельно.

По словам Реагистрировать документы :

Это где redux пригодится.

Redux предоставляет решение для управления всем состоянием приложения в одном месте, называемом магазин Отказ

Компонент тогда рассылки Государственное изменение в магазин вместо того, чтобы пройти его непосредственно к другим компонентам

Компоненты, которые должны знать о государственных изменениях, могут Подписаться в магазин.

3. Концепция Core redux

Редукс сам очень просто. Состояние приложения, которое мы создали в последней статье, могут быть представлены как общий объект, как это:

Этот объект такой же, как модель без посетителей.

Чтобы изменить это состояние в Redux, вы должны отправить Действие Отказ

Действия являются обычными объектами, описывающими Что случилось в приложении и служить единственным способом описать намерение мутировать данные Отказ Это один из Фундаментальный выбор дизайна redux.

Вот несколько примеров, которые должны быть реализованы в нашем приложении в ближайшее время.

Принуждение всех этих государственных изменений в действие даст нам четкое понимание того, что происходит в вашем приложении. Когда что-то происходит, мы видим, почему это произошло.

Теперь нам нужна функция под названием Редуктор связать эти состояния и действия вместе. Редуктор – это не что иное, как функция, которая принимает состояние и действие в качестве аргументов и возвращает Новое состояние Отказ

В мире:

Действия описывают только, что что-то случилось и не указывайте Как государственные изменения заявки в ответ Отказ Это работа редукторов.

Вот один пример редуктора для реализации в нашем приложении:

4. Redux три принципа

Я упомянул Flux несколько раз. Flux – это Узор государственного управления , не загружаемый инструмент, как Redux. Redux, с другой стороны, это Практическая реализация рисунка потока и имеет три основных принципа.

4.1 Один источник правды

Поскольку все государства существуют в одном месте, это называется Один источник правды Отказ

Это One-Store Подход Redux является одним из основных различий между ним и Много магазина флюса подход.

Каковы преимущества одного штата? Это облегчает отладку приложений или выполнять внутренние проверки и легко реализовать некоторые функции, которые ранее были трудно выполнить (например, отменить/повторить).

4.2 Штат только для чтения

Другими словами, приложение не изменяет напрямую состояние, но вместо этого выражает намерение преобразовать состояние, передавая действие.

На самом деле, если вы посмотрите на API redux, вы видите, что он состоит всего в четырех способах:

store.dispatch(action)store.subscribe(listener)store.getState()replaceReducer(nextReducer)

Как видите, нет setState () метод. Поэтому Передача действие является единственным каналом, который может мутировать состояния приложения.

4.3 Изменения выполнены с чистыми функциями

Редукторы являются чистыми функциями, которые принимают предыдущее состояние и действие и возврат нового состояния. Имейте в виду, что вы должны вернуть Новое состояние объект вместо изменения старого состояния.

Чистая функция имеет следующие характеристики:

  • Это не делает внешнюю сеть или вызовы базы данных.
  • Его возвращаемое значение зависит исключительно на значениях его параметров.
  • Его аргументы следует считаться «неизменной», то есть они не должны быть изменены.
  • Вызов чистой функции с тем же набором аргументов всегда будет возвращать одинаковое значение.

5. Разделите приложение в контейнеры и компоненты

Теперь давайте построим нашу приложение Tesla Calculator, которое мы сделали в части 1 в качестве версии Redux.

Во-первых, давайте посмотрим на Общий компонент UI макет приложения, которое будет реализовано в этой статье.

Размещение реакции и логики Redux внутри одного компонента могут быть грязными, поэтому рекомендуется создать Презентационный Компонент только для презентационных целей только и A Контейнер Компонент, верхний компонент обертки, который обрабатывает действия Redux и Dispatches.

Роль родительской контейнерной компоненты состоит в том, чтобы предоставить значения состояния к презентационным компонентам, для управления событиями и для связи с Redux от имени презентационных компонентов.

6. Перечислите состояние и действия для каждого компонента

Обратитесь к всему компонентной макету, чтобы создать список состояний и действий для каждого компонента:

TeslaCar Container :	state : wheels	action : N/A
TeslaStats Container :	state : carstats(array)	action : N/A	TeslaSpeedCounter Container : 	state : config.speed	action : SPEED_UP, SPEED_DOWN
TeslaTempCounter Container : 	state : config.temperature	action : TEMPERATURE_UP, TEMPERATURE_DOWN	TeslaClimate Container : 	state : config.climate	action : CHANGE_CLIMATE
TeslaWheel Container : 	state : config.wheel	action : CHANGE_WHEEL

7. Настройте часть 1 1 код проекта

После NPM начать Давайте убедитесь, что приложение работает.

  • Установка NPM
  • Начнем NPM

8. Создание создателей действий для каждого действия

Теперь, когда вы создали список действий, пришло время создавать Творцы действий Отказ

Action Creator – это функция, которая буквально создает объект действий. В Redux Action Creators просто возвращает объект действий и при необходимости передает значение аргумента.

Образец Action Creator Creator:

const changeWheel = (value) => {  return {    type: 'CHANGE_WHEEL',    value  }}

Эти создатели действий передаются в функцию отправки в качестве значения результата, и отправка выполняется.

dispatch(changeWheel(size))

Функция Dispatch может быть доступна непосредственно из магазина AS store.dispatch () , но в большинстве случаев он будет доступен с использованием помощника, как React-redux’s Подключиться () Отказ Мы посмотрим на соединить позже.

8.1 Создание Action.js.

Создайте файл индекса в каталоге SRC/Действия и определите создатели действия следующим образом:

SRC/Действия/index.js

import { counterDefaultVal } from '../constants/counterDefaultVal';
export const speedUp = (value) => {  return {    type: 'SPEED_UP',    value,    step: counterDefaultVal.speed.step,    maxValue: counterDefaultVal.speed.max  }}
export const speedDown = (value) => {  return {    type: 'SPEED_DOWN',    value,    step: counterDefaultVal.speed.step,    minValue: counterDefaultVal.speed.min  }}
export const temperatureUp = (value) => {  return {    type: 'TEMPERATURE_UP',    value,    step: counterDefaultVal.temperature.step,    maxValue: counterDefaultVal.temperature.max  }}
export const temperatureDown = (value) => {  return {    type: 'TEMPERATURE_DOWN',    value,    step: counterDefaultVal.temperature.step,    minValue: counterDefaultVal.temperature.min  }}
export const changeClimate = () => {  return {    type: 'CHANGE_CLIMATE'  }}
export const changeWheel = (value) => {  return {    type: 'CHANGE_WHEEL',    value  }}
export const updateStats = () => {  return {    type: 'UPDATE_STATS'  }}

Потому что нам нужно Значения по умолчанию На основании Creator Action мы определяем это постоянное значение в константах/CounterdefaultVal в каталоге SRC и импортируйте его.

SRC/Константы/CounterdefaultVal.js

export const counterDefaultVal = {  speed: {    title: "Speed",    unit: "mph",    step: 5,    min: 45,    max: 70  },  temperature: {    title: "Outside Temperature",    unit: "°",    step: 10,    min: -10,    max: 40  }}

9. Создание редукторов для каждого действия

Редукторы являются функциями, которые получают объекты состояния и действия из хранилища Redux и возвращают новое состояние, которое будет сохранено обратно в Redux.

Важно не напрямую модифицировать данное состояние здесь. Редукторы должны быть Чистые функции и должен вернуть Новое состояние Отказ

  • Функции редуктора вызываются из Контейнер это будет создано при возникновении действий пользователя.
  • Когда редуктор возвращает состояние, Redux передает новое состояние к каждому компоненту и React оказывает каждый компонент очередной раз.

9.1 Неподвижные структуры данных

  • Примитивный тип данных JavaScript (номер, строка, логический, неопределенный и нулевой) = & g t; Immuta бежать
  • Объект, массив и функция = & g t; Мута бежать

Изменения в структуре данных известны багги. Так как наш магазин состоит из государственных объектов и массивов, нам нужно реализовать Стратегия, чтобы сохранить состояние неизменной Отказ

Есть три способа изменить состояние здесь:

Es5.

// Example Onestate.foo = '123';
// Example TwoObject.assign(state, { foo: 123 });
// Example Threevar newState = Object.assign({}, state, { foo: 123 });

В приведенном выше примере первого и второго мутата состояния объекта. Второй пример мутата, потому что Объект.assign () Объединяет все свои аргументы в первый аргумент.

Третий пример не мутирует государство Отказ Он объединяет содержимое штата и {foo: 123} в Новый пустой объект который является первым аргументом.

Оператор распространения введен в ES6 предоставляет более простой способ сохранить состояние неизменной.

ES6 (ES2015)

const newState = { ...state, foo: 123 };

9.2 Создать редуктор для ChangeClimate

Во-первых, мы создадим ChangeClimate через Тестовое развитие метод.

В PAP1 наше приложение было создано через Create-React-App Итак, мы в основном используем jest как тестовый бегун.

Чрезмерный ищет тестовый файл, использующий одно из следующих конвенций именования:

Files with .js suffix in __tests__ foldersFiles with .test.js suffixFiles with .spec.js suffix

Создать teslarangeapp.spec.js в SRC/редукторах и создать тестовый случай.

describe('test reducer', () => {  it('should handle initial stat', () => {    expect(      appReducer(undefined, {})    ).toEqual(initialState)  })})

После создания теста запустите NPM Test команда. Вы должны увидеть следующее сообщение об ошибке. Это потому, что мы не написали Учредитель еще.

Чтобы сделать первый тест успешным, нам нужно создать Teslarangeapp.js В одном каталоге редукторов и напишите Первоначальное состояние и редуктор Функции.

SRC/Редукторы/Teslarangeapp.js

const initialState = {  carstats:[    {miles:246, model:"60"},    {miles:250, model:"60D"},    {miles:297, model:"75"},    {miles:306, model:"75D"},    {miles:336, model:"90D"},    {miles:376, model:"P100D"}  ],  config: {    speed: 55,    temperature: 20,    climate: true,    wheels: 19  }}
function appReducer(state = initialState, action) {  switch (action.type) {        default:      return state   }}
export default appReducer;

Затем импортируйте Teslarangeapp.js из Teslarangeapp.spec.js и установите инициал.

SRC/Редукторы/Teslarangeapp.spec.js

import appReducer from './teslaRangeApp';
const initialState =  {  carstats:[    {miles:246, model:"60"},    {miles:250, model:"60D"},    {miles:297, model:"75"},    {miles:306, model:"75D"},    {miles:336, model:"90D"},    {miles:376, model:"P100D"}  ],  config: {    speed: 55,    temperature: 20,    climate: true,    wheels: 19  }}
describe('test reducer', () => {  it('should handle initial stat', () => {    expect(      appReducer(undefined, {})    ).toEqual(initialState)  })})

Запустите тест NPM снова, и тест добится успеха.

В текущем тестовом случае тип действия {}, поэтому инициация возвращается.

Теперь давайте проверим Just_climate действие.

Добавьте следующие программы ClimateChangeState и Change_Climate для Teslarangeapp.spec.js.

const climateChangeState = {  carstats:[    {miles:267, model:"60"},    {miles:273, model:"60D"},    {miles:323, model:"75"},    {miles:334, model:"75D"},    {miles:366, model:"90D"},    {miles:409, model:"P100D"}  ],  config: {    speed: 55,    temperature: 20,    climate: false,    wheels: 19  }}
it('should handle CHANGE_CLIMATE', () => {    expect(      appReducer(initialState,{        type: 'CHANGE_CLIMATE'      })    ).toEqual(climateChangeState)  })

Затем добавьте Just_climate дело, Updatestats и Калькулятестаты Функции для Teslarangeapp.js. Затем импортируйте Batteryservice.js Это было использовано в части 1.

import { getModelData } from '../services/BatteryService';
function updateStats(state, newState) {  return {    ...state,    config:newState.config,    carstats:calculateStats(newState)  }  }
function calculateStats(state) {  const models = ['60', '60D', '75', '75D', '90D', 'P100D'];  const dataModels = getModelData();  return models.map(model => {    const { speed, temperature, climate, wheels } = state.config;    const miles = dataModels[model][wheels][climate ? 'on' : 'off'].speed[speed][temperature];    return {      model,      miles    };  });}
function appReducer(state = initialState, action) {  switch (action.type) {    case 'CHANGE_CLIMATE': {      const newState = {        ...state,        config: {          climate: !state.config.climate,          speed: state.config.speed,          temperature: state.config.temperature,          wheels: state.config.wheels        }      };      return updateStats(state, newState);    }    default:      return state  }}

Если вы проверяете результаты теста, вы можете увидеть, что два тестовых случая успешны.

То, что мы реализовали до сих пор, что изменения в состоянии, происходящее, когда пользователь включает и выключает кондиционер в приложении через тестовый бегун только из Точка зрения действия и редуктора Без магазина redux или просмотра.

9.3 Создать редуктор для других

Если вы создаете остальные тестовые случаи, ссылаясь на вышеуказанный метод, вы, наконец, определите Teslarangeapp.js Файл, в котором определены редукторы всех приложений и teslarangeapp.spec.js проверить их.

Последний код можно найти по адресу:

После завершения кода и тестирования в общей сложности семь тестовых случаев должно быть успешным.

10. Просмотры: умные и тупые компоненты

Как упоминалось в 5. Разделите приложение в контейнеры и компоненты мы создадим Презентационные компоненты (тупые компоненты) для целей презентации и Контейнерные компоненты (Умные компоненты), которые являются компонентом обертки, ответственным за действия во время передачи с Redux.

Умные компоненты Отвечает за действия Отказ Если тупой компонент под ними должен вызвать действие, умный компонент пропустит функцию через реквизиты, а тупой компонент может затем относиться к тому, что как Обратный вызов Отказ

У нас уже есть тупые компоненты для целей презентации в части 1, и повторно их повторно.

Здесь мы создаем компоненты контейнера как верхний обертка вокруг каждой тупой компонентов.

10.1 Привязка уровня просмотра

Redux нуждается в некоторой помощи для подключения магазина к представлению. Это нужно что-то, чтобы связать два вместе. Это называется Просмотр слоя связывания Отказ В приложении, которое использует реагирование, это React-redux Отказ

Технически, компонент контейнера – это просто компонент реагирования, который использует Store.subscribe () Чтобы прочитать часть дерева Strequex State и поставку реквизит к презентационному компоненту оно делает.

Следовательно, мы можем вручную создавать компоненты контейнера, но это не рекомендуется для официальных документов Redux. Это потому, что React-redux выполняет множество оптимизаций производительности Трудно выполнить вручную.

По этой причине вместо того, чтобы писать компонент контейнера вручную, мы пишем это, используя Подключиться () Функция, предоставленная React-redux.

Давайте сначала установим необходимые пакеты.

  • NPM установить –save redux
  • NPM установить –save read-redux

10.2 Контейнер Teslarcar

Использовать Подключиться () , вам нужно определить специальную функцию под названием MapstatetoProps Отказ Эта функция говорит вам Как преобразовать текущее состояние Store redux в реквизиты быть переданным на компонент презентации.

Контейнер TesLarcar принимает колеса, сохраненный в текущем магазине и передает его в реквизиту, чтобы его можно было отобразить компонентом Teslarcar. Этот реквизит будет обновлен каждый раз, когда государство обновляется.

После определения MapstatetoProps Функция, мы определили Подключиться () Функция, как показано ниже.

const TeslaCarContainer = connect(mapStateToProps, null)(TeslaCar)

connect () принимает mapdispatchtopops В качестве второго аргумента, который принимает метод отправки магазина в качестве своего первого аргумента. В компоненте Teslacar нам не нужна действие, поэтому мы должны пройти NULL.

Создать SRC/Containers/Teslacarcontainer.js и напишите код.

10.3 Контейнер Teslastats

Как и с контейнером Teslacar, определите только Мапстатумопс Функция и передайте ее для подключения () в контейнере Teslastats.

Создать SRC/Containers/Teslastatatscontainer.js и напишите код.

10.4 TeslaspeedCounter контейнер

TeslaspeedCounter контейнер Определяет дополнительное mapdispatchtopops Функция для обработки пользовательских действий, которые происходят в компоненте TeslaspeedCounter.

Создать SRC/Containers/TeslaspeedCounterContainer.js и напишите код.

10.5 Контейнер Teslatemppcounter

Teslatemppcounter контейнер Почти идентична TeslaspeedCounter, за исключением состояния и создателей действий.

Создать SRC/Containers/TeslatempcounterContainer.js и напишите код.

10,6 TeslaclimateContainer.

Создать SRC/Containers/TeslaclimateContainer.js и напишите код.

10,7 Teslawheelscontainer

Создать SRC/Containers/TeslawheelsContainer.js и напишите код.

Мы создали компоненты контейнера, соответствующие созданию компонентов презентации В части 1 через соединение () red-redux.

11. Поставщик

Давайте собрали все то, что мы сделали до сих пор и сделаем наши приложения. До сих пор мы определили Действие объектов и создан Творцы действий которые создают объекты действий. И когда происходит действие, мы создали Редукторы что на самом деле лечить и вернуть новое состояние. Затем мы создали Контейнерный компонент Это соединяет каждую из компонентов презентации к магазину Redux.

Теперь каждый контейнерный компонент нуждается в способе доступа к магазину, который является тем, что Провайдер делает. Компонент поставщика Оберните все приложение и позволяет подкомпонентам общаться с магазином через Connect () Отказ

Компонент верхнего уровня нашего приложения, App.js выглядит так:

12. Как они все работают вместе

Наконец, все кусочки головоломки были завершены. Теперь давайте посмотрим на следующую анимацию в качестве примера, когда все кусочки головоломки связаны вместе, и пользователь триггеры ускорить мероприятие.

Сейчас беги NPM начать И он будет скомпилирован нормально, и приложение будет запущено.

Но есть еще несколько вещей.

  • Сначала скопируйте все содержимое /containers/teslabattery.csss что вы создали в части 1 и добавьте их в App.csss Отказ
  • Далее, открыть /components/teslacounter/teslacounter.js и изменить OnClick Обработчик событий следующим образом: это потому, что часть 2 больше не обрабатывает обработку событий в Teslabattery.js Отказ
onClick={(e) => props.increment(e, props.initValues.title)}-->onClick={(e) => {  e.preventDefault();  props.increment(props.currentValue)}}
onClick={(e) => props.decrement(e, props.initValues.title)}-->onClick={(e) => {  e.preventDefault();  props.decrement(props.currentValue)}}
  • Далее давайте не будем использовать реквизиты неоднократно с использованием деструкурирования объекта ES6.
const TeslaCounter = (props) => (  

{props.initValues.title}

...
-->const TeslaCounter = ({ initValues, currentValue, increment, decrement }) => (  

{initValues.title}

...

Наконец, наш Redux версия Tesla Callement Calculator App завершено!

13. Еще одна вещь: redux dev Tools

Redux dev tool Делает гораздо проще просмотреть отслеживание состояния Redux и воспользоваться простыми функциями, такими как отладки времени.

Мы устанавливаем его на Chrome здесь.

Открыть App.js Файл и изменить Createstore Часть следующим образом:

const store = createStore(appReducer);-->const store = createStore(appReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
  • Проверьте браузер

Прежде чем идти на следующую часть:

Дополнительные ресурсы: