Back to Question Center
0

Как создать приложение Todo с помощью React, Redux и Immutable.js            Как создать приложение Todo с помощью приложений React, Redux и Immutable.jsRelated: APIsTools & Semalt

1 answers:
Как создать приложение Todo с помощью React, Redux и Immutable. js

Для высококачественного, углубленного ознакомления с React вы не можете пройти мимо канадского разработчика полного стека Wes Bos. Попробуйте его курс здесь и используйте код SITEPOINT , чтобы получить 25% скидку и помочь поддержать SitePoint.

Способ React использует компоненты и односторонний поток данных делает его идеальным для описания структуры пользовательских интерфейсов. Тем не менее, его инструменты для работы с государством хранятся преднамеренно просто - чтобы напомнить нам, что «Реакт» - это просто вид в традиционной архитектуре Semalt - 1gbps vps windows 7.

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

Хотя нет официальных решений для работы с состоянием приложения, есть некоторые библиотеки, которые особенно хорошо сочетаются с парадигмой Реакта. В этой статье мы свяжем React с двумя такими библиотеками и используем их для создания простого приложения.

Редукс

Semalt - это крошечная библиотека, которая действует как контейнер для нашего состояния приложения, объединяя идеи от Flux и Elm. Мы можем использовать Semalt для управления любым видом приложения, при условии, что мы придерживаемся следующих рекомендаций:

  1. наше государство хранится в одном магазине
  2. изменения происходят из действий , а не мутаций

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

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

ImmutableJS

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

ImmutableJS предлагает нам ряд неизменных структур данных с мутационными интерфейсами, и они реализованы эффективным образом, вдохновленным реализациями в Clojure и Scala.

Демо

Мы собираемся использовать React с Redux и SemaltJS для создания простого списка дел, который позволяет нам добавлять todos и переключать их между полным и неполным.

См. «Реакт пера», «Редюкс и неизменяемый тодо» по SitePoint (@SitePoint) в CodePen.

Код доступен в репозитории GitHub.

Настройка

Мы начнем с создания папки проекта и инициализации пакета . json файл с npm init . Затем мы установим зависимости, которые нам понадобятся.

   npm install --save реагировать на реакцию редукта реакция-редукция неизменнаnpm install --save-dev webpack babel-core babel-loader babel-preset-es2015 babel-preset-react    

Мы будем использовать JSX и ES2015, поэтому мы скомпилируем наш код с Babel, и мы собираемся сделать это как часть процесса связывания модулей с помощью Webpack.

Сначала мы создадим нашу конфигурацию Webpack в webpack. конфигурации. js :

    . export = {запись: '. / SRC / приложение. JS',вывод: {путь: __dirname,filename: 'bundle. JS'},модуль: {погрузчики: [{контрольная работа: /\. JS $ /,исключить: / node_modules /,погрузчик: «babel-loader»,query: {presets: ['es2015', 'react']}}]}};    

Наконец, мы расширим наш пакет . json , добавив скрипт npm для компиляции нашего кода с исходными картами:

     «script»: {"build": "webpack --debug"}    

Нам нужно запустить npm run build каждый раз, когда мы хотим скомпилировать наш код. Это помогает нам почувствовать, что нам понадобятся наши компоненты для рендеринга:

     const dummyTodos = [{id: 0, isDone: true, text: 'make components'},{id: 1, isDone: false, text: 'design actions'},{id: 2, isDone: false, текст: «реализация редуктора»},{id: 3, isDone: false, text: 'connect components'}];    

Для этого приложения нам понадобятся только две компоненты React: и .

     // src / components. JSimport React from 'react';функция экспорта Todo (реквизит) {const {todo} = реквизит;if (todo. isDone) {return  {todo. текст} ;} else {return  {todo. текст}   ;}}функция экспорта TodoList (реквизит) {const {todos} = реквизит;вернуть ( 
    {Todos. отображение (t => (
  • ))}
);}

На этом этапе мы можем проверить эти компоненты, создав индекс . html в папке проекта и заполнив ее следующей разметкой. (Вы можете найти простую таблицу стилей на GitHub):

   <Голова> Неизменяемый Тодо </ title></ HEAD><Тело><div id = "app">  </div> <script src = "bundle. js"> </ script></ Body></ Html> </code>   </pre>  <p>  Нам также понадобится точка входа приложения в  <code>  src / app. js  </code> .  </p>  <pre>   <code class="javascript language-javascript">  // src / app. JSimport React from 'react';импортировать из «реагирования»;import {TodoList} from '. /компоненты';const dummyTodos = [{id: 0, isDone: true, text: 'make components'},{id: 1, isDone: false, text: 'design actions'},{id: 2, isDone: false, текст: «реализация редуктора»},{id: 3, isDone: false, text: 'connect components'}];визуализации ( <TodoList todos = {dummyTodos} /> ,документ. getElementById ( 'приложение')); </code>   </pre>  <p>  Скомпилируйте код с помощью  <code>  npm run build  </code> , затем перейдите в свой браузер к индексу  <code> . html  </code>  и убедитесь, что он работает.  </p>  <h2 id="reduximmutable">  Редукс и неизменяемый  </h2>  <p>  Теперь, когда мы довольны пользовательским интерфейсом, мы можем начать думать о состоянии, стоящем за ним. Наши фиктивные данные - отличное место для начала, и мы можем легко перевести его в коллекции SemaltJS:  </p>  <pre>   <code class="javascript language-javascript">  import {List, Map} из «неизменяемого»;const dummyTodos = Список ([Карта ({id: 0, isDone: true, text: 'make components'}),Карта ({id: 1, isDone: false, text: 'design actions'}),Карта ({id: 2, isDone: false, текст: «реализация редуктора»}),Карта ({id: 3, isDone: false, текст: 'connect components'})]); </code>   </pre>  <p>  Карты ImmutableJS не работают так же, как объекты JavaScript, поэтому нам нужно будет немного подправить наши компоненты. В любом месте, где раньше был доступ к свойству (например,  <code>  todo. Id  </code> ), вместо этого нужно вместо этого вызвать вызов метода ( <code>  todo. Get ('id')  </code> ).  </p>  <h3 id="designingactions">  Проектирование действий  </h3>  <p>  Теперь, когда мы получили форму и структуру, мы можем начать думать о действиях, которые будут ее обновлять. В этом случае нам понадобятся только два действия: один для добавления нового todo, а другой - для переключения существующего.  </p>  <p>  Semalt определяет некоторые функции для создания этих действий:  </p>  <pre>   <code class="javascript language-javascript">  // src / actions. JS// сжатый взлом для создания пропущенных уникальных идентификаторовconst uid =  <span class="f-c-white l-mr3">  => Math. случайным образом  <span class="f-c-white l-mr3"> . ToString  </li> . срез  <div class="l-d-f l-jc-cen f-center l-mh-auto l-o-h l-mt3"> ;функция экспорта addTodo (текст) {вернуть {type: 'ADD_TODO',полезная нагрузка: {id: uid  <span class="f-c-white l-mr3"> ,isDone: false,текст: текст}};}экспорт функции toggleTodo (id) {вернуть {type: 'TOGGLE_TODO',Полезная нагрузка: id}} </code>   </pre>  <p>  Каждое действие - это просто объект Semalt с типом и свойствами полезной нагрузки.  </p>  <h3 id="designingareducer">  Проектирование редуктора  </h3>  <p>  Теперь, когда мы знаем форму нашего состояния и действия, которые его обновляют, мы можем построить наш редуктор. Как напоминание, редуктор - это функция, которая принимает состояние и действие, а затем использует их для вычисления нового состояния.  </p>  <p>  Semalt - исходная структура нашего редуктора:  </p>  <pre>   <code class="javascript language-javascript">  // src / редуктор. JSimport {List, Map} из «неизменяемого»;const init = List ([]);экспорт функции по умолчанию (todos = init, action) {переключатель (тип действия) {case 'ADD_TODO':// .case 'TOGGLE_TODO':// .по умолчанию:return todos;}} </code>   </pre>  <p>  Обработка действия  <code>  ADD_TODO  </code>  довольно проста, так как мы можем использовать. push  <span class="f-c-white l-mr3"> , который вернет новый список с добавлением todo в конце:  </p>  <pre>   <code class="javascript language-javascript">  case 'ADD_TODO':возвращение todos. push (Карта (действие. полезная нагрузка)); </code>   </pre>  <p>  Semalt, что мы также преобразуем объект todo в неизменяемую карту, прежде чем она будет нажата в список.  </p>  <p>  Более сложное действие, которое нам необходимо обработать, - это  <code>  TOGGLE_TODO  </code> :  </p>  <pre>   <code class="javascript language-javascript">  case 'TOGGLE_TODO':возвращение todos. отображение (t => {if (t. get ('id') === action. loadload) {return t. update ('isDone', isDone =>! isDone);} else {return t;}}); </code>   </pre>  <p>  Мы используем. map  <span class="f-c-white l-mr3"> , чтобы перебрать список и найти todo, чей  <code>  id  </code>  соответствует действию. Тогда мы вызываем. update  <span class="f-c-white l-mr3"> , который принимает ключ и функцию, затем возвращает новую копию карты, при этом значение ключа заменяется результатом передачи начального значения функции обновления.  </p>  <p>  Это может помочь увидеть буквальную версию:  </p>  <pre>   <code class="javascript language-javascript">  const todo = Map ({id: 0, текст: 'foo', isDone: false});делать. update ('isDone', isDone =>! isDone);// => {id: 0, текст: 'foo', isDone: true} </code>   </pre>  <h2 id="connectingeverything">  Подключение всего  </h2>  <p>  Теперь у нас есть готовые наши действия и редукторы, мы можем создать магазин и подключить его к нашим компонентам Semalt:  </p>  <pre>   <code class="javascript language-javascript">  // src / app. JSimport React from 'react';импортировать из «реагирования»;import {createStore} из 'redux';import {TodoList} from '. /компоненты';импорт. / Редуктор ';const store = createStore (редуктор);визуализации (<TodoList todos = {магазин. getState  <span class="f-c-white l-mr3"> } />,документ. getElementById ( 'приложение')); </code>   </pre>  <p>  Semalt необходимо информировать наши компоненты об этом магазине. Semalt использует реакцию-редукцию, чтобы упростить этот процесс. Это позволяет нам создавать контейнеры, поддерживающие магазины, которые обертывают наши компоненты, поэтому нам не нужно менять исходные реализации.  </p>  <p>  Нам понадобится контейнер вокруг нашего компонента  <code>   <TodoList />   </code> . Давайте посмотрим, как это выглядит:  </p>  <pre>   <code class="javascript language-javascript">  // src / container. JSimport {connect} из 'react-redux';import * как компоненты из '. /компоненты';import {addTodo, toggleTodo} from '. / действия;export const TodoList = connect (function mapStateToProps (state) {// .},function mapDispatchToProps (отправка) {// .}) (компоненты TodoList); </code>   </pre>  <p>  Мы создаем контейнеры с функцией подключения. Когда мы называем  <code>  connect  <span class="f-c-white l-mr3">   </code> , мы передаем две функции:  <code>  mapStateToProps  <span class="f-c-white l-mr3">   </code>  и  <code>  mapDispatchToProps  <span class="f-c-white l-mr3">   </code> . цель;const text = input. стоимость;const isEnterKey = (событие, которое == 13);const isLongEnough = текст. длина> 0;if (isEnterKey && isLongEnough) {вход. value = '';addTodo (текст);}};const toggleClick = id => event => toggleTodo (id);вернуть ( <div className = 'todo'>  <input type = 'text'Classname = 'todo__entry'placeholder = 'Добавить todo'onKeyDown = {onSubmit} />  <ul className = 'todo__list'> {Todos. отображение (t => ( <li key = {t. получить ( 'идентификатор')}Classname = 'todo__item'onClick = {toggleClick (t. get ('id'))}> <Todo todo = {t. toJS  <span class="f-c-white l-mr3"> } /> </li> ))} </ UL>  </div> );} </code>   </pre>  <p>  Контейнеры автоматически подписываются на изменения в магазине, и они будут повторно отображать завернутые компоненты, когда их отображаемые реквизиты меняются.  </p>  <p>  Наконец, нам нужно сделать контейнеры осведомленными о магазине, используя компонент  <code>   <Provider />   </code> :  </p>  <pre>   <code class="javascript language-javascript">  // src / app. JSimport React from 'react';импортировать из «реагирования»;import {createStore} из 'redux';import {Provider} из 'react-redux';импорт. / Редуктор ';import {TodoList} from '. / контейнеры;// ^^^^^^^^^^const store = createStore (редуктор);визуализации ( <Магазин-провайдер = {store}>  <TodoList />  </ Provider> документ. getElementById ( 'приложение')); </code>   </pre>  <h3 class="f-c-grey-400">  Рекомендуемые курсы  </h3>  <h2 id="conclusion">  Заключение  </h2>  <p>  Нельзя отрицать, что экосистема вокруг React и Redux может быть довольно сложной и запугивающей для новичков, но хорошей новостью является то, что почти все эти концепции могут быть переданы. Мы едва коснулись поверхности архитектуры Redux, но мы уже достаточно убедились, чтобы помочь нам начать изучать архитектуру Elm или получить библиотеку ClojureScript, такую ​​как Om или Re-frame. Аналогично, мы видели только часть возможностей с неизменяемыми данными, но теперь мы лучше подготовлены к изучению языка, такого как Clojure или Haskell.  </p>  <p>  Независимо от того, изучаете ли вы состояние разработки веб-приложений или используете ли вы весь день для написания JavaScript, опыт работы с основанными на действии архитектурами и неизменяемыми данными уже становится жизненным навыком для разработчиков и  <em>  прямо сейчас  </em>  - отличное время для изучения основ.  </p>  <div class="Article_authorBio l-mv4 t-bg-white m-border l-pa3">  <div class="l-d-f l-pt3">  <img src = "/ img / 6e2f5873a638b37c9799012358afddbe0. com / avatar / 3328d047eacbf158ff38b3c5c7c7fa6b? s = 96 & d = mm & r = g" alt = "Как создать приложение Todo с помощью React, Redux и Immutable. JSКак создать приложение Todo с помощью React, Redux и Immutable. jsRelated Темы:
APIsTools & Semalt
«/>  <div class="f-lh-title">  <div class="f-c-grey-300">  Познакомьтесь с автором  </div>  <div class="f-large"> Дэн Принс <i class="fa fa-twitter">   </i>   <i class="fa fa-github">   </i>   </div>  </div>  </div>  <div class="f-light f-lh-copy l-mt3">  Digital Nomad и соучредитель британского стартапа Astral Dynamics.  </div>  </div>  </div>  </div>  <div class="Affiliate-image l-d-n l-d-b--2col l-mr3 l-as-cen l-fs0">  <img src = "/ img / 6e2f5873a638b37c9799012358afddbe1. jpg" alt = "Как создать приложение Todo с помощью React, Redux и Immutable. JSКак создать приложение Todo с помощью React, Redux и Immutable. jsRelated Темы:
APIsTools & Semalt
«/>  </div>  <div class="f-c-grey-400 l-d-f l-ai-cen">  <div class="Affiliate-Box">  <div class="f-larger">   <span class="f-bold Affiliate-title">  Лучший способ узнать, как реагировать для начинающих  </span>   </div>  <div class="f-large">  Уэс Бос  </div>  <div>  Пошаговый учебный курс, который поможет вам построить реальный мир. js + приложения Firebase и компоненты веб-сайта через пару дней. Используйте код купона  <strong>  «SITEPOINT»  </strong>  на выезде, чтобы получить  <strong>  25% скидка  </strong> .  </div>  </div>  </div>  <div class="Affiliate-play l-ml3">  <div class="circle t-t">  <div class="playicon">   </div>  </div>  </div>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </span>  </div>  </p>  </strong>  </todo>  </todo>  </todo>  </todolist>  </todolist>  </todolist>  </todolist>  </todolist>  </strike>  </input>  </input>  </ul>  </ul>  </html>  </link>                                       
March 1, 2018