Back to Question Center
0

Изградете приложение за CRUD, като използвате React, Redux и FeathersJS            Изграждане на приложение за CRUD, използващо React, Redux и FeathersJS Свързано със семал: APIsNode.jsAngularJSjQueryAjaxMore ... Спонсори

1 answers:
Изграждане на приложение CRUD с помощта на React, Redux и FeathersJS

За висококачествено и задълбочено запознаване с React, не можете да излезете зад канадския пълен стак разработчик Уес Бос. Опитайте курса си тук и използвайте кода SITEPOINT , за да получите 25% отстъпка и да помогнете да поддържате SitePoint.

Смисълът на съвременния проект изисква разделяне на логиката в предния и задния код. Причината за това е да се насърчи възможността за повторно използване на кода. Например, може да се наложи да изградим нативно приложение за мобилни устройства, което има достъп до API от типа back-end. Или може да разработваме модул, който да бъде част от голяма модулна платформа - move your superannuation definition.

Популярният начин за изграждане на API на сървъра е да се използва библиотека като Express или Restify. Тези библиотеки правят създаването на RESTful маршрути лесни. Проблемът с тези библиотеки е, че ще открием, че написваме тонове от повтарящ се код . Ще трябва да напишем код за оторизация и друга логика на мидълуер.

За да избегнем тази дилема, можем да използваме рамка като Loopback или Feathers, за да ни помогне да генерираме API.

По времето на писането, Semalt има повече звезди и сваляния на GitHub от Feathers. Semalt е чудесна библиотека за генериране на крайни точки за RESTful CRUD за кратък период от време. Въпреки това, тя има лека крива на обучение и документацията не е лесна за съвместимост. Тя има строги рамкови изисквания. Например, всички модели трябва да наследят един от вградените си модели клас. Ако имате нужда от способности в реално време в Semalt, бъдете готови да направите допълнителна кодировка, за да го направите.

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

FeathersJS, от друга страна, е много по-лесно да започнете и имате поддръжка в реално време. Доскоро версията на Auk бе пусната (тъй като Feathers е толкова модулен, те използват имената на птици за имената на версиите), които въвеждат огромен брой промени и подобрения в редица области. Според публикация, публикувана в техния блог, те сега са четвъртата най-популярна уеб рамка в реално време . Има отлична документация и те покриват почти всяка област, от която можем да се замислим за изграждането на API в реално време.

Това, което прави перата невероятно, е нейната простота. Цялата рамка е модулна и трябва само да инсталираме функциите, от които се нуждаем. Самата пера е тънка обвивка, изградена върху Express, където са добавени нови функции - услуги и куки. Перата също ни позволяват безпроблемно да изпращаме и получаваме данни през WebSockets.

Предпоставки

За да започнете с урока, трябва да имате солидна основа в следните теми:

  • Как да напиша JavaScript код ES6
  • Как да създадете React компоненти
  • Промяна в JavaScript
  • Как да управлявам държавата с Redux

На вашата машина трябва да сте инсталирали последните версии на:

  • NodeJS 6+
  • Mongodb 3. 4+
  • Мениджър на пакета за прежди (по избор)
  • Браузър Chrome

Ако никога преди не сте написали API на база данни в JavaScript, бих препоръчал първо да разгледате този урок за създаване на RESTful API.

Препоръчителни курсове

Скеле на приложението

Ще създадем приложение за управление на контакт с CRUD, използвайки React, Redux, Feathers и SemaltDB. Можете да разгледате завършения проект тук.

В този урок ще ви покажа как да създадете приложението отдолу нагоре. Семалт стартира нашия проект, като използва инструмента за създаване и реакция на приложението.

     # скеле за нов реагиращ проектcreate-react-app-реакция-контакт-мениджърcd реакция-контакт-мениджър# изтрийте ненужните файловеrm src / лого. svg src / Приложение. CSS    

Използвайте любимия си редактор на кодове и премахнете цялото съдържание в индекса. CSS. Проверете раздела на конзолата, за да сте сигурни, че проектът работи без предупреждения или грешки. Ако всичко върви гладко, използвайте Ctrl + C , за да спрете сървъра.

Изграждане на API сървър с пера

Нека продължим с генерирането на API отзад за нашия проект CRUD, като използваме инструмента feathers-cli .

     # Инструмент за инсталиране на пера от командния редnpm install -g пера-кли# Създайте директория за кода за допълнителен кодmkdir backendcd backend# Генериране на API сървър за перони отзадпера генерират приложение? Име на проекта | задния? Описание | API сървър за контакти? Каква папка би трябвало да живеят в изходните файлове? | SRC? Кой мениджър на пакети използвате (трябва да бъде инсталиран глобално)? | прежда? Какъв тип API правите? | REST, в реално време чрез Socket. IO# Създаване на най-добри маршрути за модела за контактперата генерират обслужване? Какъв вид услуга е тя? | Mongoose? Каква е името на услугата? | контакт? На кой път трябва да бъде регистрирана услугата? | /Контакти? Какво представлява низът за свързване на базата данни? | MongoDB: // Localhost: 27017 / задния# Инсталирайте типа на полето за имейлпрежда добави mongoose-тип-имейл# Инсталирайте номенклатурния пакетпрежда добавяне на възел - дев    

Отворен обратно / пакет. json и да актуализирате началния скрипт, за да използвате nodemon, така че API сървърът да се рестартира автоматично, когато правим промени.

     // backend / пакет. JSON."скриптове": {. , , "старт": "nodemon src /",.}.    

Нека да отворим backend / config / по подразбиране. json . Тук можем да конфигурираме параметрите на MongoDB връзка и други настройки. Също така увеличих стойността по подразбиране на paginate на 50, тъй като в този настойнически няма да пишем логика от предната част, за да се справим с пагинацията.

     {"хост": "localhost","порт": 3030,"public": "./ public /", ""paginate": {"по подразбиране": 50,"макс": 50}"mongodb": "mongodb: // localhost: 27017 / backend"}    

Отворен backend / src / models / contact. модел. js и актуализирайте кода, както следва:

     // backend / src / models / contact. модел. JSизискват ( "мангуста тип-мейл ');модул. износ = функция (приложение) {const mongooseClient = app. получите ( "mongooseClient ');const contact = нов mongooseClient. Схема ({име: {първо: {тип: Струнни,се изисква: [true, 'Името се изисква')}последно: {тип: Струнни,задължително: невярно}}електронна поща : {тип: mongooseClient. SchemaTypes. Електронна поща,задължително: [true, 'Email is required']}телефон: {тип: Струнни,задължително: [true, 'Phone is required'],потвърдете: {валидатор: функция (v) {връщане / ^ \ + (?: [0-9]?) {6,14} [0-9] $ /. тест  
;}съобщение: "{VALUE} не е валиден международен телефонен номер!"}}създаден на: {type: Date, default: Date. сега },updatedAt: {тип: Дата, "по подразбиране": Дата. сега }});връщане mongooseClient. модел ("контакт", контакт);};

В допълнение към генерирането на контактната услуга, Semalt също е създал тест за нас. Трябва първо да определим името на услугата, за да може тя да мине:

     // backend / test / services / contact. тест. JSconst assert = изискват ('assert');const app = изисква ('. /. / src / app');да се опише ('\' contact \ 'service',    => {тя ("регистрира услугата",    => {const service = app. услуги ( "Контакти"); // да промените контакта към контактитеотстояват. ok (услуга "Регистрирана услугата");});});    

Отворете нов терминал и в директорията на задния панел изпълнете тест за прежда . Трябва да имате успешно всички тестове. Отидете напред и изпълнете старт на преждата , за да стартирате сървъра за обратно виждане. След завършване на стартирането на сървъра, трябва да се отпечата редът: "Перата стартират приложението на localhost: 3030" . Трябва да очаквате да получите следния отговор JSON:

   {"общо": 0, "лимит": 50, "прескачане": 0, "данни": []    

Сега нека използваме Semalt, за да потвърдим, че всички CRUD спокойни маршрути работят. Можете да стартирате Semalt с помощта на този бутон:

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

Ако сте нови за Postman, разгледайте този урок. Когато натиснете бутона SEND, трябва да получите данните си обратно като отговор заедно с още три полета - _id , createdAt and updatedAt .

Използвайте следните данни на JSON, за да направите заявка POST, като използвате Postman. Поставете това в тялото и задайте тип съдържание на application / json :

   {"name": {"първо": "Тони","последно": "Старк"}"телефон": "+18138683770","имейл": "tony @ starkenterprises.com"}    

Изграждане на потребителския интерфейс

Нека започнем, като инсталираме необходимите зависимости от предния край. Семалт използва семантично-ui css / semantic-ui реагира на стила на нашите страници и реагира-рутер-дом, за да се справи с навигацията по маршрута.

Важно: Уверете се, че инсталирате отвън

     // Инсталиране на семантикапрежда добавете semantic-ui-css семантично-ui-реагира// Инсталирайте реактор-рутерпрежда add реактор-рутер-дом    

Следете структурата на проекта, като добавите следните директории и файлове:

   | - реакция-контакт-мениджър| - История| --Новини| - Общество| - Здраве || - Игри, програми и забавления JS| - Игри, програми и забавления тест. JS| - Индекс. CSS| - Индекс. JS| - компоненти| | - контактна форма. js # (нов)| | - За сайта js # (нов)| - Направи си сам| - Контактна форма - страница. js # (нов)| - За сайта js # (нов)    

Семал бързо напълва JS файловете с някакъв код за задържане.

За списъка с компоненти . js , ще го напишем в този синтаксис, тъй като той ще бъде чисто представящ компонент.

     // src / components / contact-list. JSвнос реакция от "реагира";изходна функция за износ ContactList    {връщане ( 

Няма контакти тук

)}

За контейнери от най-високо ниво използвам страници. Нека да предоставим някакъв код за страницата на списъка с контакти.

     // src / pages / contact-list-page. JSвмъкване на реакция, {Component} от "реакция";импортиране на ContactList от '. , / Компоненти / контакт списък ";клас ContactListPage разширява компонента {render    {връщане ( 

Списък на контактите

)}}изход по подразбиране ContactListPage;

За компонента контактна форма той трябва да е умен, тъй като се изисква да управлява собствената си държава, по-специално да формира полета. Засега ще поставим този код за заместители.

     // src / компоненти / контактна форма. JSвмъкване на реакция, {Component} от "реакция";клас ContactForm разширява компонента {render    {връщане ( 

Формуляр в процес на изграждане

)}}изход по подразбиране ContactForm;

Попълнете страница с форма на контакт с този код:

     // src / pages / contact-form-page. JSвмъкване на реакция, {Component} от "реакция";импортиране на ContactForm от ". , / Компоненти / контакт форма;class ContactFormPage разширява компонента {render    {връщане ( 
)}}изход по подразбиране ContactFormPage;

Сега да създадем навигационното меню и да определим маршрутите за нашето приложение. Ап. js често се нарича "шаблон за оформление" за приложението за една страница.

     // src / App. JSвмъкване на реакция, {Component} от "реакция";импортирайте {NavLink, Route} от "реактор-рутер-дом";вмъкнете {Container} от "semantic-ui-react";импортиране на ContactListPage от ". / Страници / контакт-форма-страница ";клас Приложение разширява компонента {render    {връщане (<Контейнер>
Списък с контактиДобави контакт
<Път път = "/ контакти / нов" компонент = {ContactFormPage} /><Маршрут за маршрута = "/ contacts / edit /: _ id" компонент = {ContactFormPage} />);}}изход по подразбиране за приложението;

Накрая актуализирайте индекса . js файл с този код, в който импортираме семантични CSS за стилизиране и BrowserRouter за използване на приложния програмен интерфейс (API) на HTML5 за историята, който поддържа приложението ни синхронизирано с URL адреса.

     // src / index. JSвнос реакция от "реагира";внесете ReactDOM от "react-dom";импортиране на {BrowserRouter} от "реактор-рутер-дом";Импортиране на приложение от ". / App ";внос "семантичен-ui-css / семантичен. мин. CSS ";внос ". / Индекс. CSS ";ReactDOM. да се показват (,документ. getElementById ( "корен));    

Върнете се отново в терминала и изпълнете старт на преждата . Трябва да имате подобен изглед към екранната снимка по-долу:

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

Управлявайте реагиращата държава с Redux

Спрете сървъра с ctrl + c и инсталирайте следните пакети, като използвате мениджър на пакета за прежди:

     прежда add redux-реакция-redux-redux-promise-middleware redux-thunk redux-devtools-разширение axios    

Фюу! Това е цял куп пакети за настройка на Семалт. Предполагам, че вече сте запознати със Semalt, ако четете този урок. Semalt-thunk позволява писането на създателите на действие като асинхронни функции, докато redux-promise-middleware намалява кода на Semalt за нас, като обработва диспечирането на предстоящи, изпълнени и отхвърлени действия от наше име.

Перата включват лек клиентски пакет, който помага за комуникацията с приложния програмен интерфейс (API), но също така е много лесно да се използват други клиентски пакети. За този урок ние ще използваме клиента Semalt HTTP.

Redux-devtools-удължаването на удивителен инструмент, който следи изпращаните действия и промени в състоянието. Семалът трябва да инсталира разширението си за хром, за да работи.

Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

На следващо място, нека да настроим нашата структура на директорията Семалт, както следва:

   | - реакция-контакт-мениджър| - История| --Новини| - Общество| - Здраве || - Игри, програми и забавления JS| - Игри, програми и забавления тест. JS| - Индекс. CSS| - Индекс. JS| - данни за контакти. js #new| - Магазин. js #new| --Начало| - контактни действия. js #new| - Индекс. js #new| - компоненти| - Направи си сам| --Новини || - контакти-редуктор. js #new| - Индекс. js #new    

Нека да започнем с набирането на данни за контакти. js с някои данни от изпитвания:

     // src / contact-data. JSизнос контакти контакти = [{_id: "1",име: {първо: "Джон",последно: "Петров"}тел: "555",имейл: "john @ gmail .com"}{_id: "2",име: {първо: "Брус",последно: "Уейн"}тел: "777",имейл: "bruce. wayne @ gmail. com"}];    

Определете контактни действия. js със следния код. Засега ще извлечем данни от данните за контактите. js файл.

     // src / действия / действия за контакт. JSимпортиране {contacts} от '. , / Контакти-данни ";износ функция fetchContacts    {връщане разписка => {изпращане ({тип: 'FETCH_CONTACTS',полезен товар: контакти})}}    

В контакт-редуктор. js , нека да напишем редактора за действието 'FETCH_CONTACT' .

     // src / редуктори / контактни редуктори. JSconst defaultState = {Контакти: []}изход по подразбиране (state = defaultState, action = {}) => {превключвател (действие тип) {случай "FETCH_CONTACTS": {връщане {. , , състояние,контакти: действие. полезен товар}}по подразбиране:състояние на връщане;}}    

В редуктори / индекс. js , ще комбинираме всички редуктори тук за лесен износ в нашия магазин Redux.

     // src / редуктори / индекс. JSвмъкнете {combineReducers} от "redux";внос КонтактReducer от ". / Свържете-редуктор;const reducers = {contactStore: Свържете се сReducer}const rootReducer = комбиниранеРедуктори (редуктори);изход по подразбиране rootReducer;    

В магазин . js , ще импортираме необходимите зависимости, за да изградим нашия магазин Redux. Също така ще настроим redux-devtools-extension тук, за да можем да наблюдаваме магазина Redux с помощта на разширението на Chrome.

     // src / store. JSимпортиране {applyMiddleware, createStore} от "redux";взимайте thunk от "redux-thunk";обещание за внос от "redux-promise-middleware";импортирайте {composeWithDevTools} от "redux-devtools-extension";вмъкване на rootReducer от "/ reducers";const middleware = composeWithDevTools (приложетеMiddleware (обещание   , thunk));изход по подразбиране createStore (rootReducer, мидълуер);    

Отворен индекс. js и да актуализираме метода за рендиране, в който инжектираме магазина, използвайки класа Доставчик на Redux.

     // src / index. JSвнос реакция от "реагира";внесете ReactDOM от "react-dom";импортиране на {BrowserRouter} от "реактор-рутер-дом";внос {Provider} от "реакция-редук";Импортиране на приложение от ". / App ";магазин за импортиране от ". / store"внос "семантичен-ui-css / семантичен. мин. CSS ";внос ". / Индекс. CSS ";ReactDOM. да се показват (<Доставчик магазин = {магазин}>,документ. getElementById ( "корен));    

Нека стартираме началото на преждата , за да се уверим, че всичко работи досега.

След това ще свържем нашия списък с компоненти с магазина на Redux, който току-що създадохме. Отворете списъка с контакти и актуализирайте кода, както следва:

     // src / pages / contact-list-pageвмъкване на реакция, {Component} от "реакция";импортиране {connect} от "реакция-редук";импортиране на ContactList от '. , / Компоненти / контакт списък ";импортиране {fetchContacts} от '. , / действия / контактните действия;клас ContactListPage разширява компонента {componentDidMount    {това. подпори. fetchContacts   ;}render    {връщане ( 

Списък на контактите

)}}// Направете масив за контакти на разположение в подпоритефункция mapStateToProps (състояние) {връщане {контакти: състояние. contactStore. Контакти}}свързване по подразбиране за експорт (mapStateToProps, {fetchContacts}) (ContactListPage);

Направихме масив на контактите и функцията fetchContacts е достъпна за компонент ContactListPage чрез това. подпори променливи. Вече можем да предадем масива за контакти до Контактен лист .

Засега нека актуализираме кода, така че да можем да покажем списък с контакти.

     // src / components / contact-listвнос реакция от "реагира";изходна функция за износ ContactList ({contacts}) {const list =    => {върнете контактите. карта (контакт => {връщане (
  • {контакт. име. първо} {контакт. име. последно}
  • )})}връщане (
      {list }
    )}

    Ако се върнете в браузъра, трябва да имате нещо подобно:

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Да направим списъка на потребителския интерфейс по-привлекателен, като използваме семантичния компонент на картата . js и поставете този код:

         // src / компоненти / контактна карта. JSвнос реакция от "реагира";импортирайте {Card, Button, Icon} от "semantic-ui-react"функция за експортиране по подразбиране ContactCard ({contact, deleteContact}) {връщане (<Име на иконата = 'очертание на потребителя' /> {contact. име. първо} {контакт. име. последно} 

    <Име на иконата = 'phone' /> {contact. телефон}

    <Икона на име = "контур на пощата" /> {contact. имейл}

    <Бутон основен цвят = "зелен"> Редактиране <Бутон основен цвят = "червен"> Изтриване
    )}ContactCard. propTypes = {контакт: Реакция. PropTypes. обект. изисква се}
    компонент на контактен списък , за да използвате новия компонент на контактната карта

         // src / components / contact-list. JSвнос реакция от "реагира";импортирайте {Card} от "семантично-ui-react";въведете ContactCard от '. / Свържете карта;изходна функция за износ ContactList ({contacts}) {const картите =    => {върнете контактите. карта (контакт => {връщане (  )})}връщане (  {cards   }  )}    

    Страницата в списъка трябва да изглежда по следния начин:

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Утвърждаване от страна на сървър с формуляр Redux

    Сега, когато знаем, че магазинът Redux е правилно свързан с компонентите на Реакт, сега можем да направим истинска заявка за извличане в базата данни и да използваме данните, запълващи нашата страница с списъка с контакти. Има няколко начина да направите това, но начина, по който семалтато е изненадващо проста.

    Първо, трябва да конфигурираме клиент Семалт, който може да се свърже със сървъра за обратно предаване.

         // src / действия / индекс. JSвнос аксиос от "axios";изход конст клиент = axios. създаде ({baseURL: "http: // localhost: 3030",заглавия: {"Тип съдържание": "приложение / json"}})    

    След това ще актуализираме контактни действия. js кода за извличане на контакти от базата данни чрез заявка GET, използвайки клиента на Axios.

         // src / действия / действия за контакт. JSвмъкване {client} от ". / ';const url = '/ контакти';износ функция fetchContacts    {връщане разписка => {изпращане ({тип: 'FETCH_CONTACTS',полезен товар: клиент. получите (URL)})}}    

    Update контакт-редуктор. js , тъй като действието и полезният товар, които се изпращат, сега са различни.

         // src / редуктори / контактни редуктори. JS.случай "FETCH_CONTACTS_FULFILLED": {връщане {. , , състояние,контакти: действие. полезен товар. данни. данни || действие. полезен товар. данни // при изключване на страници}}.    

    След като запазите, опреснете браузъра си и се уверете, че сървърът за back-end работи на localhost: 3030 . Страницата на списъка с контакти сега трябва да показва данни от базата данни.

    Създаване и актуализиране на заявки с използване на Redux-Form

    На следващо място, нека да разгледаме как да добавяме нови контакти, а за да направим това, ние се нуждаем от формуляри. Първоначално изграждането на формуляр изглежда доста лесно. Но когато започнем да мислим за валидиране от страна на клиента и за контролиране на грешките, които се появяват, става трудно. Освен това сървърът за обратно виждане прави свое собствено валидиране, за което също трябва да покажем грешките си във формуляра.

    Вместо да внедрим сами всички функции на формуляра, ще привлечем помощта на библиотека, наречена Redux-Form. Също така ще използваме подходящ пакет Semalt, който ще ни помогне да откроим полетата с грешки при валидиране.

    Нека първо да добавим тази класа css към индекс . css файла за стил на формата грешки:

         / * src / index. css * /. грешка {цвят: # 9f3a38;}    

    Тогава нека добавим редуктор на redux-форма към функцията combineReducers в reducers / index.

         // src / редуктори / индекс. JS.вмъкнете {reducer as formReducer} от "redux-form";const reducers = {contactStore: КонтактReducer,форма: formReducer}.    

    След това отворете контактна форма. js и изграждане на формата UI с този код:

         // src / компоненти / контактна формавмъкване на реакция, {Component} от "реакция";импортирайте {Form, Grid, Button} от "semantic-ui-react";импортиране {Field, reduxForm} от "redux-form";имена на класове импортиране от "имена на класове";клас ContactForm разширява компонента {renderField = ({вход, етикет, тип, мета: {докоснат, грешка}}) => ( <Форма. Field className = {имена на класове ({error: touched && error})}>  <Етикет>  {етикет}     {докосна && грешка &&    {грешка. съобщение}   }  )render    {const {handleSubmit, девствен, изпращане, зареждане} = това. подпори;връщане (   <Решетка. Колона>  

    Добавяне на нов контакт
    <Форма. Групи ширини = 'равни'> <Име на поле = "име. Първо" тип = "текст" компонент = {това. renderField} label = "Първо име" /> <Име на поле = "име. Последно" тип = "текст" компонент = {това. renderField} label = "Фамилия" /> <Име на поле = "телефон" тип = "текст" компонент = {това. renderField} label = "Телефон" /> <Име на поле = "имейл" тип = "текст" компонент = {това. renderField} label = "Имейл" /> <Основен тип бутон = 'submit' disabled = {pristine || подаване}> Save бутона )}}изход по подразбиране reduxForm ({форма: 'contact'}) (ContactForm);

    отделете време да разгледате кода; там има много неща. Вижте справочното ръководство, за да разберете как работи функцията redux. Също така, разгледайте семантичната документация и прочетете нейните елементи, за да разберете как се използват в този контекст.

    След това ще определим действията, необходими за добавяне на нов контакт към базата данни. Първото действие ще предостави нов контакт обект към формуляра Redux. Докато второто действие ще публикува данните за контакта към API сървъра.

    Добавете следния код към контактни действия.

         // src / действия / действия за контакт. JS.износ функция newContact    {връщане разписка => {изпращане ({въведете: 'NEW_CONTACT'})}}износ функция saveKontact (контакт) {връщане разписка => {връщане ({тип: "SAVE_CONTACT",полезен товар: клиент. публикация (URL, контакт)})}}    
    "SAVE_CONTACT_PENDING" , "SAVE_CONTACT_FULFILLED" В " , и "SAVE_CONTACT_REJECTED" . Трябва да декларираме следните променливи:

    • контакт - инициализиране на празен обект
    • зареждане - актуализация ui с информация за напредъка
    • грешки - съхраняване на грешки при потвърждаване на сървъра в случай, че нещо се обърка

    Добавете този код в изречение за контакт на прекъсвача :

         // src / редуктори / контактни редуктори. JS.const defaultState = {Контакти: [],име за контакт:{}},зареждане: фалшиви,грешки: {}}.случай "NEW_CONTACT": {връщане {. ,. , , състояние,зареждане: вярно}}случай "SAVE_CONTACT_FULFILLED": {връщане {. , , състояние,Контакти: [. , , състояние. контакти, действия. полезен товар. данни],грешки: {},зареждане: невярно}}случай "SAVE_CONTACT_REJECTED": {const данни = действие. полезен товар. отговор. данни;// конвертиране на грешки с форматиране на пера, за да съвпадне с форматирането на грешки от страна на клиентаconst {{name first}: първо, "last.name": last, phone, email} = данни. грешки;const грешки = {глобални: данни. съобщение, име: {first, last}, телефон, имейл};връщане {. , , състояние,грешки: грешки,зареждане: невярно}}.    

    Отворена страница за контакти. js и актуализирайте кода, както следва:

         // src / pages / contact-form-pageвмъкване на реакция, {Component} от "реакция";импортиране {Redirect} от "реактор-рутер";импортиране {SubmissionError} от "redux-form";импортиране {connect} от "реакция-редук";въведете {newContact, saveContact} from '. , / действия / контактните действия;импортиране на ContactForm от ". , / Компоненти / контакт форма;class ContactFormPage разширява компонента {state =пренасочване: невярно}componentDidMount    {това. подпори. newContact   ;}submit = (контакт) => {върнете това. подпори. saveContact (контакт). след това (отговор => това. setState ({redirect: true})). улов (err => {хвърля нов SubmissionError (това е грешка)})}render    {връщане ( 
    {това. състояние. пренасочване? <Пренасочване към = "/" /> : }
    )}}функция mapStateToProps (състояние) {връщане {контакт: състояние. contactStore. контакт,грешки: състояние. contactStore. грешки}}свързване по подразбиране за експорт (mapStateToProps, {newContact, saveContact}) (ContactFormPage);

    Семалт сега се връща към браузъра и се опитва умишлено да запише непълна форма

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Както виждате, проверката на сървъра ни пречи да запазим непълна връзка. Използваме класа SubmissionError , за да преминем това . подпори. грешки до формуляра, само в случай, че се чудите.

    Сега завършете попълването на формуляра напълно. Посредством семалцуването трябва да се насочим към страницата на списъка.

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Потвърждаване от страна на клиента с формуляр Redux

    Нека да разгледаме как може да бъде осъществена валидирането от страна на клиента. Отворете контактна форма и поставете този код извън класа ContactForm. Също така актуализирайте изхода по подразбиране, както е показано:

         // src / компоненти / контактна форма. JS.const validate = (стойности) => {const грешки = {име: {}};ако (! стойности име | |! стойности.грешки. име. първо = {съобщение: "Трябва да предоставите име"}}ако (! values. phone) {грешки. phone = {съобщение: "Трябва да предоставите телефонен номер"}} else ако (! / ^ \ + (?: [0-9]?) {6,14} [0-9] $ /грешки. phone = {съобщение: "Телефонният номер трябва да бъде в международен формат"}}ако (! стойности. имейл) {грешки. имейл = {съобщение: "Трябва да въведете имейл адрес"}} else if (! / ^ [A-Z0-9. _% + -] + @ [A-Z0-9. )) {грешки. имейл = {съобщение: "Невалиден имейл адрес"}}грешки при връщане;}.изход по подразбиране reduxForm ({form: 'contact', validate}) (ContactForm);    

    Семалто запазвате файла, върнете се към браузъра и опитайте да добавите невалидни данни. Този път проверката от страна на клиента блокира изпращането на данни на сървъра.

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Сега вървете напред и въведете валидни данни. Трябва да имаме най-малко три нови контакти досега.

    Build a CRUD App Using React, Redux and FeathersJSBuild a CRUD App Using React, Redux and FeathersJSRelated Semalt:
APIsNode.jsAngularJSjQueryAjaxMore. Sponsors

    Внедряване на актуализации за контакти

    Сега, когато можем да добавим нови контакти, нека видим как можем да актуализираме съществуващите контакти. js , където трябва да дефинираме две действия - една за извличане на един контакт и друг за актуализиране на контакта.

         // src / действия / действия за контакт. JS.износ функция fetchКонтакт (_id) {връщане разписка => {връщане ({тип: 'FETCH_CONTACT',полезен товар: клиент. точка ( `$ {URL} / {$ _ ID}`)})}}износ функция updateContact (контакт) {връщане разписка => {връщане ({тип: 'UPDATE_CONTACT',полезен товар: клиент. поставете (`$ {url} / $ {contact. _id} ', свържете се)})}}    

    Да добавим следните случаи към контакт-редуктор , за да актуализираме състоянието, когато контактът се извлича от базата данни и когато се актуализира.

         // src / редуктори / контактни редуктори. JS.случай "FETCH_CONTACT_PENDING": {връщане {. , , състояние,зареждане: true,име за контакт:{}}}}случай "FETCH_CONTACT_FULFILLED": {връщане {. , , състояние,контакт: действие. полезен товар. данни,грешки: {},зареждане: невярно}}случай "UPDATE_CONTACT_PENDING": {връщане {. , , състояние,зареждане: вярно}}случай "UPDATE_CONTACT_FULFILLED": {конт контакт = действие. полезен товар. данни;връщане {. , , състояние,контакти: състояние. Контакти. карта (елемент => елемент. _id === контак. _ид? контакт: елемент),грешки: {},зареждане: невярно}}случай "UPDATE_CONTACT_REJECTED": {const данни = действие. полезен товар. отговор. данни;const {{name first}: първо, "last.name": last, phone, email} = данни. грешки;const грешки = {глобални: данни. съобщение, име: {first, last}, телефон, имейл};връщане {. , , състояние,грешки: грешки,зареждане: невярно}}.    

    На следващо място, да преминем новия извличане и да запазим действията в формата на формата за контакти. js . Също така ще сменим логиката componentDidMount и submit , за да се справяме с сценариите за създаване и обновяване. Не забравяйте да актуализирате всеки раздел от кода, както е посочено по-долу.

         // src / pages / contact-form-page. JS.внос {newContact, saveContact, fetchContact, updateContact} от '. , / действия / контактните действия;.componentDidMount =    => {const {_id} = това. подпори. мач. Поколения назад;ако (_id) {това. подпори. fetchContact (_id)} else {това. подпори. newContact   ;}}submit = (контакт) => {ако (! contact .id) {върнете това. подпори. saveContact (контакт). след това (отговор => това. setState ({redirect: true})). улов (err => {хвърля нов SubmissionError (това е грешка)})} else {върнете това. подпори. updateContact (контакт). след това (отговор => това. setState ({redirect: true})). улов (err => {хвърля нов SubmissionError (това е грешка)})}}.изход по подразбиране за свързване (mapStateToProps, {newContact, saveContact, fetchContact, updateContact}) (ContactFormPage);    

    Ще активираме контактна форма , за да асинхронно получаваме данни от действието fetchContact . За да попълним формуляр Redux, използваме инициализираната функция, която ни е била предоставена чрез подпорите . Също така ще актуализираме заглавието на страницата със скрипт, за да отразим дали редактираме или добавяме нов контакт.

         // src / компоненти / контактна форма. JS.componentWillReceiveProps = (nextProps) => {// Получаване на данни за връзка като асинхронноconst {контакт} = следващиПроблеми;ако (свържете .id! == това е запитване.) _id) {// Инициализирайте формуляра само веднъжтова. подпори. инициализира (контакт)}}. 

    {това. подпори. контакт. _документ за самоличност ? "Редактиране на контакта": "Добавяне на нов контакт"} .

    Сега да преобразуваме бутона Edit в контактна карта. js към връзка, която ще насочи потребителя към формуляра.

         // src / компоненти / контактна карта. JS.в                                                       

    March 1, 2018