Сейчас я пытался использовать реагирование на мои личные проекты на пару недель, но я узнал, что в интернете нет ни одного примера (что я мог найти), которые я хочу, что я хочу в реальном жизненном сценарии.
Асинхронные HTTP-запросы, анимации погрузки, страницы ошибок и т. Д. Никто из этих вещей не покрывается одним кратким характером, который можно найти на первых двух страницах Google.
Сказав это, я взял один Пример Это взяло меня достаточно далеко, и начал исследовать и строить на его вершине.
Что мы будем делать?
Мы собираемся построить простое сообщение для веб-приложения.
Для этого мы собираемся построить очень простые API отдыха в Node.js, используя REST-API-стартер и веб-сайт на основе реагирования. JS, Redux и Bootstrap.
Что мне нужно будет следовать этим руководству?
Во-первых, установка Node.js 6, IDE и браузер (который вы, вероятно, уже имеете, как вы читаете это). Инструкции о том, как установить Node.js можно найти здесь Отказ
Во-вторых, монтаж Python 2.7. Если вы находитесь в Mac OS или системе на основе Ubuntu, у вас уже есть. Инструкции о том, как установить Python можно найти здесь Отказ
Все команды, которые я предоставлю устанавливать, бегать и выполнять пробуждение на Linux Mint 18. Они, вероятно, будут работать на Mac OS без какой-либо проблемы. Если вы работаете над Windows, мне очень жаль.
Можем ли мы уже начать кодировать?
AllRight, прежде всего, давайте сделаем наши каталоги.
$ mkdir todo-api $ mkdir todo-site
API Project
Теперь начнем с API. Мы собираемся в CD
в каталог API и запустите NPM init
Отказ
$ cd todo-api $ npm init
Вы можете оставить все значения по умолчанию.
Теперь у нас есть проект узла там, мы собираемся установить REST-API-стартер
и uuid
(Для удостоверения личности и вещей).
$ npm install --save rest-api-starter uuid
Теперь REST-API-стартер
Требуется крошечный файл конфигурации в подкаталоге под названием config
Отказ
$ mkdir config $ cd config && touch default.json
config/default.json
Файл должен выглядеть точно так же, как приведен ниже:
{ "app": { "http": { "port": 8100, "host": "0.0.0.0", "queue": 10, "secret": "", "transactionHeader": "X-REST-TRANSACTION" }, "log": { "level": "info", "transports": [ { "type": "console" } ] } } }
Теперь, давайте код нашего отдыха API. Нам нужны поддержка CORS, чтобы иметь возможность легко развиваться в нашей локальной среде и трех обработке:
- Пост
/Тодос
: Создайте элемент. - Получить
/Тодос
: Получить все предметы. - Патч
/TODOS/: ID
: Отметьте элемент как сделать или отменить.
Кроме того, обработчик опций для каждого пути должен быть реализован для поддержки CORS. Итак, наш index.js
Файл будет выглядеть так:
const uuid = require('uuid'); const serveBuilder = require('rest-api-starter').server; const todos = []; const router = (app) => { app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods", "GET, POST, PATCH, OPTIONS"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); app.options('/todos', (request, response) => response.status(200).send()); app.post('/todos', (request, response) => { const todo = { 'id': uuid.v4(), 'isDone': false, 'text': request.body.text }; todos.push(todo); response.send(todo); }); app.get('/todos', (request, response) => { response.send(todos); }); app.options('/todos/:id', (request, response) => response.status(200).send()); app.patch('/todos/:id', (request, response) => { let result = null; todos.forEach((todo) => { if (todo.id === request.params.id) { todo.isDone = !todo.isDone; result = todo; } }); if (!result) { response.status(404).send({'msg': 'todo not found'}); } else { response.send(result); } }); }; serveBuilder(router);
Теперь добавьте «Пуск»: «Узел index.js»
к Скрипты
Раздел вашего файла Package.json Чтобы запустить сервер. Бег NPM запустить начало
В корне проекта API вы будете прослушивать свой сервер на http://localhost: 8100
Отказ
Проект сайта
Теперь мы собираемся CD на проект сайта и запустите NPM init
там. По умолчанию здесь тоже хорошо.
$ cd todo-site $ npm init
И теперь мы устанавливаем зависимости, которые нам нужны:
$ npm install --save babel-core babel-loader babel-preset-es2015 babel-preset-react bootstrap jquery superagent webpack react react-dom react-redux redux redux-thunk style-loader css-loader
WebPack
Мы будем использовать WebPack, чтобы транпилировать и унифицировать весь код в файл UNA под названием bundle.js
Так будет удобно добавить "построить": "WebPack --debug"
и «Подавать»: «NPM Run Build && Python -m SimpleHttpserver 8080 "
в раздел скриптов в нашем package.json.
Теперь нам понадобится webpack.config.js
Отказ
const webpack = require('webpack'); module.exports = { entry: { main: './src/app.js' }, output: { path: __dirname, filename: 'bundle.js' }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: [ 'es2015', 'react' ] } }, { test: /\.css$/, loader: "style-loader!css-loader" }, { test: /\.(png|jpg|gif|ttf|svg|woff|woff2|eot)$/, loader: "url-loader" } ] }, plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", bootstrap: "bootstrap" }) ] };
Этот конфигурация WebPack транкирует все файлы JavaScript, использующих ES6 и JSX, а затем объединяет их вместе со всеми их зависимостями, в одном большом файле под названием bundle.js
Отказ
Если какой-либо стильют требуется от src/app.js.
, он импортирует его и добавит его в комплект (после любого импорта, сделанного из таблиц стилей), и сгенерированный скрипт пучка добавит <СТИЛЬ>
Тег к HTML.
Это также использует Устанавливается
Чтобы выставить jQuery и Bootstrap, поэтому мы можем забыть о импорте их.
Таблицы стилей
Теперь начнем с какой-то структуры. Давайте создадим каталог под названием CSS
В корне проекта и добавьте следующие app.csss
Отказ
@import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
Эта таблица Styleshet просто импортирует загрузку, но вы можете добавить пользовательский стиль и импортировать любую таблицу, которую вы хотите там. Это должно быть въездной точкой для всех стилей в проекте.
HTML. Выход на сайт.
Тогда мы создаем наши index.html
в проекте.
Todo List
Это довольно простой HTML-файл. Он имеет название, ViewStor, рекомендованный Bootstrap, A Div
с идентификатором приложение
и импорт нашего пакета.
Этот дивы под названием приложение
Будет наш контейнер приложений. Мы скажем отреагировать, чтобы сделать его компоненты там.
Реагистрационные компоненты
Давайте напишем наши компоненты React.js. Актуальный компонент представляет собой независимый кусок кода, который получает некоторые реквизиты и отображает HTML из этого реквизита. Следует просто отреагировать, код компонента не должен ничего знать о redux. Просто презентация. (Я не могу подчеркнуть этого достаточно).
Создайте каталог под названием SRC
В корне проекта и напишите код ниже в файл с именем Компоненты.js
Отказ
import React from 'react'; function Todo(props) { const { todo } = props; if (todo.isDone) { return{todo.text}} else { return {todo.text} } } function TodoList(props) { const { todos, toggleTodo, addTodo } = props; const onSubmit = (event) => { event.preventDefault(); const textInput = document.getElementById('todo-input'); const text = textInput.value; if (text && text.length > 0) { addTodo(text); } textInput.value = ''; }; const toggleClick = id => event => toggleTodo(id); return ( ); } function Layout(props) { return () } function ProgressBar(props) { const { completed } = props; const style = { 'width': completed + '%'}; return ({props.children}To Do List Keep it organized.
) } export function TodoPage(props) { const {state, toggleTodo, addTodo, retrieveTodos } = props; if (state.error) { return ({completed}% Complete); } else if (state.initialized) { return ( {state.error.toString()}) } else { retrieveTodos(); return ( ); } }
Это наш презентационный слой. Мы экспортируем одну функцию, называемую Тодопаж
, который использует некоторые компоненты, доступные только внутри модуля.
Эти компоненты получают состояние приложения и три действия: TOGGLETODO, ADDTODO, Retrovetodos. Компоненты не знают, что они делают, они просто знают, как их вызывать, и они даже не заботятся о возвращенной стоимости.
Обратите внимание, что компоненты получают состояние и действия, и просто заботится о том, как отображается состояние, и как эти действия отображаются с событиями HTML.
API клиент
Теперь, давайте напишем наш клиент API, используя SuperaGent
и ES6 обещания. Под каталог называется SRC
Создано в корне нашего проекта, напишите следующий код в файле под названием Client.js
Отказ
import * as superagent from "superagent"; export function get() { return new Promise((resolve, reject) => { superagent.get("http://localhost:8100/todos") .end((error, result) => { error ? reject(error) : resolve(result.body); }); }); } export function add(text) { return new Promise((resolve, reject) => { superagent.post("http://localhost:8100/todos") .send({'text': text}) .end((error, result) => { error ? reject(error) : resolve(result.body); }); }); } export function toggle(id) { return new Promise((resolve, reject) => { superagent.patch("http://localhost:8100/todos/" + id) .end((error, result) => { error ? reject(error) : resolve(result.body); }); }); }
Этот модуль экспортирует три функции:
- Получить: выполняет запрос на получение
/Тодос
в нашем API, чтобы получить все делать предметы. - Добавить: Выполняет запрос на пост
/Тодос
в нашем API, чтобы добавить товар. - Toggle: выполняет запрос на патч на
/Тодос/: ID
Чтобы изменитьIsdone
Флаг этого товара.
Действия Redux
Давайте поговорим о действиях …
Действия, в redux, являются кусками информации, которые отправляются в магазин. Эти полезные нагрузки вызывают модификации в состоянии приложения.
Действия в основном способ высказывания redux “Эй! Это произошло!”.
Предупреждение : Не фактические модификации, состояние приложения Shippoud рассматривается как неизменный объект. Вы никогда не должны изменять состояние, но скопируйте его, измените копию и продолжайте идти. Больше на нем дальше вниз.
Действия генерируются с помощью действий. Эти строители являются функциями, которые вызываются с некоторой информацией и возврат действия, которое отправляется в магазин через отправка
Функция, предоставленная redux.
Интересная концепция, необходимая для реальных мировых приложений, являются асинхронными действиями. Это на самом деле не просто часть информации, но другая функция, которая получает отправка
Функция как параметры и, после некоторых асинхронных операций отправляют другое действие. Давайте объясним это с некоторым кодом.
Напишите следующий код в файл под названием Actions.js
под SRC
каталог.
import { get, add, toggle } from './client'; export function addTodo(text) { return (dispatch) => { add(text) .then(get) .then((todos) => dispatch(receiveTodos(todos))) .catch((err) => dispatch(error(err))); }; } export function toggleTodo(id) { return (dispatch) => { toggle(id) .then(get) .then((todos) => dispatch(receiveTodos(todos))) .catch((err) => dispatch(error(err))); }; } export function retrieveTodos() { return (dispatch) => get() .then((todos) => dispatch(receiveTodos(todos))) .catch((err) => dispatch(error(err))) } function receiveTodos(todos) { return { type: 'RECEIVE_TODOS', payload: todos } } function error(err) { return { type: 'ERROR', payload: err }; }
Мы здесь определяем все поведение нашего приложения.
Наше приложение должно получить делать элементы из API, переключите их и создайте их. Эти действия асинхронные.
ADDTODO Action Builder возвращает асинхронное действие, которое после публикации нового сделать товар на API и извлекать все делать элементы снова, отправлять
Получение
действие. По ошибке, это рассылаетОшибка
. действие.Action Builder Toggletodo возвращает асинхронное действие, которое после переключения до употребления элемента на API и еще раз извлеките все элементы, отправляющие
Получение
действие. По ошибке, это рассылаетОшибка
. действие.Действие Retrovetodos Action Builder возвращает асинхронное действие, которое после того, как восстановить все делать предметы из API, отправляет
Получение
действие. По ошибке, это рассылаетОшибка
. действие.
Обратите внимание, что это (не так, как они определяются здесь, мы увидим, как) являются действиями, которые используются нашими компонентами для обработки событий HTML.
Два других действия являются обычными действиями, которые получают некоторые данные и возвращает полезную нагрузку.
Действие поступления Action Builder возвращает действие типа
Recept_todos
с восстановленным тодосом как полезной нагрузки.Ошибка Action Builder возвращает действие типа
Ошибка
с полученной ошибкой как полезной нагрузки.
Это может звучать с толку. Я думаю, что redux не просто понять государственный менеджер, его концепции довольно трудно понять, но если вы поместите это на практике и прочитаете код, который вы получите ему многое.
Редуктор Redux
Это приведет нас к редукторам. Редуктор – это функция, которая принимает текущее состояние приложения и действие. Как уже говорилось, действие – это способ сказать, что что-то случилось, и редуктор захватывает это событие/информацию и делает то, что нужно сделать с государством, чтобы повлиять на это событие на него.
По сути, они получают текущее состояние приложения и выполняемое действие (событие или что-то, например, пользователь, например, кликующий) и вернуть новое состояние приложения.
Давайте посмотрим больше кода. Напишите следующий код в файл под названием redeber.js
под SRC
каталог.
const init = {'todos': [], 'error': false}; export default function(state=init, action) { switch(action.type) { case 'RECEIVE_TODOS': return {'todos': action.payload, 'error': false, 'initialized': true}; case 'ERROR': return {'todos': [], 'error': action.payload, 'initialized': true}; default: return state; } }
Этот редуктор определяет начальное состояние применения и уход за обработкой действий, которые он получает.
Если действие, которое он получил имеет тип Recept_todos
он возвращает новое состояние, гарантируя, что Ошибка
. ложно, Инициализирован
правда и Тодос
Содержит полученные Todos.
Если действие, которое он получил имеет тип Ошибка
он возвращает новое состояние, гарантируя, что Ошибка
. Содержит ошибку Ocurred, Инициализирован
правда и Тодос
является пустым массивом.
Если действие, которое он получил, не имеет обработчика, он просто проходит через текущее состояние приложения, так как никакие изменения не должны применяться.
Извините, я так много повторяю, но эта концепция мне давала: Компоненты React Compents получают подруги Redux и движутся к ним на HTML-событиях. Эти события отправляются в редукторы Redux, чтобы сделать то, что они должны сделать с государством, основанным на информации, предоставленной действием.
Контейнерные компоненты
Еще одна новая концепция: контейнеры. Контейнеры – это тип компонента, они называются Контейнерные компоненты
Отказ Они делают соединение между компонентами реагирования (которые являются просто презентационными компонентами и ничего не знают о Redux), а также действия redux.
Они в основном обертывают компонент реагирования и захватывают состояние и действия и отображают их в реквизиты.
Давайте посмотрим код. Напишите следующий код в файл под названием Containers.js
под SRC
каталог.
import { connect } from 'react-redux'; import * as components from './components'; import { addTodo, toggleTodo, retrieveTodos } from './actions'; export const TodoPage = connect( function mapStateToProps(state) { return { state: state }; }, function mapDispatchToProps(dispatch) { return { addTodo: text => dispatch(addTodo(text)), toggleTodo: id => dispatch(toggleTodo(id)), retrieveTodos: () => dispatch(retrieveTodos()) }; } )(components.TodoPage);
Это хватает нашего Тодопаж
, наши действия и государство, и ставит их в реквизит, чтобы наш компонент посмотреть. Это где все склеено.
Запуск веб-приложения
Давайте пойдем на нашу точку входа в заявку сейчас. Напишите следующий код в файл под названием app.js
под SRC
Отказ
import '../css/app.css'; import React from 'react'; import { render } from 'react-dom'; import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import { Provider } from 'react-redux'; import reducer from './reducer'; import { TodoPage } from './containers'; const store = createStore(reducer, applyMiddleware(thunk)); document.addEventListener("DOMContentLoaded", function() { render(, document.getElementById('app') ); });
Этот файл импортирует наш файл входа CSS, наш редуктор и контейнер для ToPage (не компонент, контейнер).
Затем он создает магазин Redux (в основном, где живет государство). Возможно, вы заметили, что наш редуктор не обрабатывает любые наши асинхронные действия, вот почему мы передаем это ApplyMiddleware (Thunk)
к Createstore
. Redux-Thunk
Позаботьтесь о обращении с асинхронными действиями, как это.
Теперь мы ждем, пока нужно загрузить, а затем звонить React’s оказывать
функция. Эта функция получает компонент и элемент HTML-контейнера (это наше приложение Div # от Index.html).
Компонент, который мы передаем к оказывать
Функция – это Провайдер
Тег, с только один ребенок (Это важно, у него не может быть более одного ребенка), который наш Тодопаж
Контейнерный компонент. Мы передаем наш магазин в Провайдер
метка кстати.
Вы готовы пойти
Теперь мы можем запустить NPM запустить служить
В корне проекта сайта и NPM запустить начало
В корне проекта API. Теперь мы можем посетить http://localhost: 8080/
и используйте наш список, чтобы сделать список.
Заключение
Я нахожу эту пару (React, Redux), чтобы иметь довольно сложный нагрев, но, как только вы получите это, приложения записываются быстро, а код тоже выглядит великолепно. Да, иногда это много котельной, но выглядит красиво, и это на самом деле тоже очень хорошо выполняет.
Я пришел из мира jQuery, затем перешел к углованию. JS, а теперь я переехал, чтобы реагировать. JS и Redux и мне на самом деле нравится.
Вы можете найти код на этот пример здесь Отказ
Увидимся в комментариях!
Оригинал: “https://dev.to/svinci/react-js-web-site-example-almost-real-life-like”