Technical Fat Redux Бесплатное видеоруководство 20 000 словесных статей 24 эпизода видео

React.js Redux
Technical Fat Redux Бесплатное видеоруководство 20 000 словесных статей 24 эпизода видео

Изучая основы React, я считаю, что вы должны хорошо понимать React, и вы также можете создавать несколько простых проектов React (обратите внимание, что здесь я говорю о простых проектах). Почему вы можете делать только несколько простых проектов?Потому что React — это простой и легкий фреймворк уровня представления.

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

ReduxЭто лучшая структура уровня данных в текущей экосистеме React, поэтому я придумал отдельную статью для систематического объяснения Redux.

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

Цель 1000 эпизодов бесплатных видео, 339 эпизодов были завершены. (339 эпизодов внешнего списка видео)

Если вы новичок в основах React, сначала изучите основы React:

p0: Список бесплатных видеоуроков по основам React (28 эпизодов)

(1,5x Новый Свет)

  1. Предисловие к курсу React (315)

  2. Введение в сравнение React и Vue (314)

  3. Создание среды разработки React (313)

  4. Знакомство с каталогом проекта, сгенерированным скаффолдингом (312)

  5. Объяснение HelloWorld и компонентов (311)

  6. Введение в синтаксис JSX в React (310)

  7. Пример React — сервисное меню Miss Sister (309)

  8. Пример React - меч хорошо начищен, теории меньше не бывает (308)

  9. Пример React — босс, я хочу добавить колокольчик (307)

  10. Пример React — хотя меч хорош, старая талия его не выдерживает (306)

  11. React Advanced — Несколько мест для JSX, чтобы не наступить на яму (305)

  12. React Advanced — простые фрагменты React (304)

  13. React Advanced — Разделение компонентов (303)

  14. React Advanced — передача значений родительско-дочерних компонентов (303)

  15. React Advanced — поток данных с одним элементом и другие (302)

  16. React Advanced — установка и использование инструментов отладки (301)

  17. React Advanced — значение прохождения проверки PropTypes (300)

  18. Как использовать React Advanced-Ref (299)

  19. React Advanced — Объяснение жизненного цикла — 1 (298)

  20. React Advanced — Объяснение жизненного цикла — 2 (297)

  21. React Advanced — Объяснение жизненного цикла — 3(296)

  22. React Advanced — жизненный цикл повышает производительность программы (295)

  23. React Advanced — запрос данных Axios (294)

  24. React Advanced — Axios запрашивает EasyMock (# 293)

  25. React Advanced — анимация React с помощью CSS3 (292)

  26. React Advanced — анимация ключевых кадров CSS3 (291)

  27. Реагировать на расширенную группу реагирования-перехода (290)

  28. React Advanced — производство и написание анимации Multi-DOM (289)

p0: Бесплатное видеоруководство по Redux (24 эпизода)

  1. Основы — Понимание Redux и введение в статьи (339)

  2. Основы — Рабочий процесс Redux (338)

  3. Введение в Ant Design и инициализация среды (337)

  4. Создание пользовательского интерфейса с помощью Ant Design(336)

  5. Создание репозиториев в Redux — хранилище и редьюсер (335)

  6. Основы — установка Redux Dev Tools (334)

  7. Foundation - Испытайте процесс Redux через ввод (333)

  8. Основы — создание ToDoList в Redux (332)

  9. Foundation — Реализация функции удаления ToDoList с помощью Redux (331)

  10. Основы — Советы по написанию Redux на работе — 1 (330)

  11. Основы - Советы по написанию Redux на работе - 2(329)

  12. Закуски - Redux заполняет три ямы (328)

  13. Расширенный — метод разделения пользовательского интерфейса компонента и бизнес-логики (327)

  14. Дополнительно — заполнение ям и компоненты без состояния в Redux (326)

  15. Расширенный — Axios получает данные асинхронно и объединяется с Redux (325)

  16. Advanced — установка и настройка промежуточного ПО Redux-thunk (324)

  17. Продвинутый - Как использовать Redux-thunk (323)

  18. Advanced - установка и настройка Redux-saga (322)

  19. Дополнительно - Получите список TodoList с помощью Redux-saga (321)

  20. Введение и установка Advanced-React-Redux (320)

  21. Продвинутый — провайдер и подключение в React-redux (319)

  22. Advanced - модификация данных react-redux (318)

  23. Advanced-React-redux добавляет данные списка (317)

  24. Оптимизация программы React-redux (окончание) (316)

Сначала здесь приводится основная схема этого курса, а также знания, которые вы можете усвоить.Redux免费视频教程

P01: Основы — знакомство с Redux и введение в статьи

На самом деле, я могу найти эту статью, которая доказывает, чтоReduxЭто можно рассматривать как базовое понимание.Эта статья подходит для чтения младшими фронтенд-разработчиками.В ней подробно объясняются базовые знания о Redux.После понимания базовых знаний он будет постепенно увеличивать расширенное содержание Redux.

Содержание курса относится к «React и Redux по-простому», но они перестроены и добавлены со своим пониманием.Если у автора есть какие-либо возражения или просьбы удалить его, вы можете связаться с блогером.

Само введение

Есть много старых друзей и несколько новых. Итак, позвольте представиться. Мое онлайн-имя "Технический жир". Я занимаюсь программированием более 11 лет. Я не делал продуктов, которые меняют мир, и при этом я не являюсь экспертом в этой области. В последние 2 года я сохранил привычку вести блог, и моя цель — выпустить 1000 бесплатных видеороликов, чтобы помочь новичкам, которые только что вошли в программу фронтенда. В настоящее время я все еще программист, который каждый день перемещает кирпичи, мне нравится моя нынешняя работа, и я также мечтаю стать штатным лектором, и я много работаю для своей мечты.

Каждую неделю я выкладываю около 3 эпизодов бесплатных видеоуроков, так что вы можете следить за мной.

Если вы хотите изучать знания, связанные с React, с техническим жиром,Вы можете войти в группу QQ: 159579268

Введение в Редукс

Redux — это инструмент приложения JavaScript для управления состоянием данных и состоянием пользовательского интерфейса. Поскольку разработка одностраничных приложений JavaScript (SPA) становится все более и более сложной, JavaScript должен управлять большим количеством состояний, чем когда-либо, а Redux упрощает управление. (Redux поддерживает React, Angular, jQuery и даже чистый JavaScript)

Вы можете увидеть, как Redux упрощает управление состоянием через картинку (картинка взята с сайта «Front-end Records», если есть какие-либо нарушения, пожалуйста, свяжитесь, чтобы удалить)

Redux简化图

Как видно из рисунка, если мы не используем Redux, нам очень хлопотно передавать состояние. В Redux данные можно поместить в хранилище данных (хранилище-хранилище общедоступного состояния), где состоянием можно управлять единообразно, а затем, какой компонент используется, перейти к строю, чтобы найти состояние. Если фиолетовый компонент на пути хочет изменить состояние, просто изменитеstoreв состоянии, а затем другие компоненты будут автоматически следовать изменениям в.

Отношения между Flux и Redux

Многие друзья спросят меня, говорю ли я о Flux? Я могу дать вам четкий ответ здесь, чтобы не говорить об этом.

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

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

Частота обновления

Я тоже программист, мне приходится работать каждый день, а еще мне приходится работать сверхурочно всю ночь, поэтому каждую неделю я обновляю около трех серий видео. Присоединяйтесь к группе QQ, чтобы получать обновленную информацию в первый раз. Давайте учиться вместе.

P02: Основы — Рабочий процесс Redux

Знания, которые предстоит усвоить на этом уроке, очень важны, их можно усвоить толькоReduxрабочий процесс, вы можетеReduxИмейте прозрачное понимание. Если у вас есть только официальные фотографии или вы сами смотрите документы, это все равно немного сложно. Но если у вас много контактов с Хун Ченом или вы похожи на Толстого Брата, вы человек, которому нравится Мисс Сестра, тогда этот процесс очень прост. (смотреть видео)

Официальное изображение Redux

Давайте сначала посмотрим на официальные изображения, и я также попытаюсь объяснить это, так что не вините. Поскольку эта вещь не очень хорошо понята, официальная очень абстрактна.

Redux简化图

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

Схема моего понимания

Я объясню вам эту картину как опытный водитель много лет.Вы можете полностью понять эту картину как процесс большого меча.Если у вас мало опыта, или вы девушка, я могу понять это как процесс заимствования книги. Я, конечно, еще беру в пример меч (картинка нарисована мной, очень некрасиво).

Redux简化图

React ComponentsРавнозначен высокопоставленному чиновнику, а потом идем делать "большой меч", то что мы видим первое этоAction Creators«Мама Санг», мы сказали, что я искал Сяохуна, я был постоянным клиентом. "Мама-сан" вернуласьStore, тогда пустьReducerПосмотрите, занята ли «Сяохун» (в ее нынешнем состоянии), если она не занята, пусть подойдет к высшим чиновникам.

У меня также есть библиотечная версия для девочек и детей младшего возраста.

Redux简化图

Я объясню эту версию в видео и не буду вводить слишком много в тексте.

Суммировать: Процесс реализации Redux прост, но если посмотреть на официальную картинку и понять ее непросто, то можно связать ее с окружающими вещами, что гораздо проще. Важно заявить, что вы должны понимать этот рабочий процесс, что очень важно для вашего обучения Redux.

P03: Базовый-Ant DesignВведение и инициализация среды

Ant DesignЭто среда пользовательского интерфейса для разработки на уровне предприятия с хорошими визуальными и динамическими эффектами. Набор фреймворков пользовательского интерфейса с открытым исходным кодом Ali, он не только поддерживаетReact,а такжеngа такжеVueверсии, я думаю, независимо от того, какой у вас интерфейсный фреймворк,Ant DesignОба являются хорошим выбором. обычноAntDesignУпоминается какantd. В настоящее время насчитывается около 50 000 звезд, что является лидером среди фреймворков пользовательского интерфейса React.

Официальный сайт:ant.design/index-cn

Инициализировать проект

Здесь я предполагаю, что вы уже видели мой «Бесплатный видеоурок по React16», поэтому я думаю, что вы поняли основные моменты этого процесса, я просто проведу вас через него.

  1. Если у вас нет инструмента для создания лесов, вам необходимо установить:
npm install -g create-react-app
  1. Создавайте проекты напрямую с помощью инструментов поддержки
  D:  //进入D盘
  mkdir ReduxDemo   //创建ReduxDemo文件夹
  cd ReduxDemo      //进入文件夹
  create-react-app demo01  //用脚手架创建React项目
  cd demo01   //等项目创建完成后,进入项目目录
  npm  start  //预览项目

Этот проект готов, давайте удалим ненужные файлы и сведем структуру кода к минимуму. Удалить все файлы в SRC, оставив только одинindex.js, и файл index.js также очищается.

Быстрое создание базовой структуры кода

записыватьindex.jsФайл, этот файл является базовым файлом, и базовый код такой же.

import React from 'react';
import ReactDOM from 'react-dom'
import TodoList from './TodoList'

ReactDOM.render(<TodoList/>,document.getElementById('root'))

записыватьTodoList.jsфайл, этот файл можно использовать сSimple React SnippetsГенерируйте быстро. Введите первыйimrc, затем введитеccc

код показывает, как показано ниже:

import React, { Component } from 'react';
class TodoList extends Component {
    render() { 
        return ( 
            <div>Hello World</div>
         );
    }
}
export default TodoList;

После этого считается, что основная конструкция проекта завершена, и можно открывать браузер, чтобы увидеть эффект. Установите его следующимAnt DesignФреймворк пользовательского интерфейса тоже.

УстановитьAntDesign

использовать здесьnpmдля установки, конечно, вы можете использоватьyarnспособ установки.

npm install antd --save

yarnСпособ установки:

yarn add antd

Если ситуация с вашей сетью плохая, лучше всего использоватьcnpmустановить. После того, как программа будет установлена, вы сможете ею пользоваться. Установка этой сети у меня дома занимает очень много времени, поэтому я подожду завершения установки, а затем научусь ее использовать на следующем занятии.

P04: Основы — ИспользованиеAnt DesignСделать пользовательский интерфейс

Базовая среда разработки иAntDesignустановка. Для этого классаAnt DesignСделать интерфейс TodoList. Эта статья не будетAnt DesignПодробное объяснение, просто чтобы интерфейс курса выглядел лучше, если у вас есть сильная потребность в обучении или желание, вы можете взглянутьAnt DesignОфициальные документы, документы на китайском языке, сложностей нет. Рисунок – это стиль, который будет выполнен в конце этого урока.

Redux案例

Внедрить стили CSS

В использованииAnt DesignПервое, что нужно сделать, это сначала ввести стили CSS, чтобы компоненты пользовательского интерфейса могли нормально отображаться только со стилями. прямо в/src/TodoList.jsпрямо в файлеimportПредставлять.

import 'antd/dist/antd.css'

Напишите поле ввода

После введения стилей CSS вы можете использовать его с удовольствием.antdвнутренний<input>Коробка, когда вы используете, вам нужно сначала ввестиInputкомпоненты. Полный код выглядит следующим образом:

import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input } from 'antd'

class TodoList extends Component {
    render() { 
        return ( 
            <div>
                <div>
                    <Input placeholder='jspang' style={{ width:'250px'}}/>
                </div>
            </div>
         );
    }
}
export default TodoList;

существуетInputкомпонент, мы устанавливаемstyle, обратите внимание на установку без одинарных или двойных кавычек.

После написания вы можете просто увидеть эффект.

Кнопка «Написать»

Ant DesignОн также предоставляет богатые и красивые компоненты кнопок, напрямую используя простейшиеPrimaryкнопка. Прежде чем использовать компонент кнопки, его также необходимо сначала представить.Чтобы компонент выглядел лучше, некоторыеMarginстиль, код выглядит следующим образом:

import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input , Button } from 'antd'

class TodoList extends Component {
    render() { 
        return ( 
            <div style={{margin:'10px'}}>
                <div>
                    <Input placeholder='Write something' style={{ width:'250px', marginRight:'10px'}}/>
                    <Button type="primary">增加</Button>
                </div>
            </div>
         );
    }
}
export default TodoList;

Компонент списка составляет список

также использоватьAnt DesginСоставьте список todoList, перед созданием мы сначалаclassВнешний объявить массив данных, содержимое массива можно легко записать.


const data=[
    '早8点开晨会,分配今天的开发工作',
    '早9点和项目经理作开发需求讨论会',
    '晚5:30对今日代码进行review'
]

Затем введите компонент List, код выглядит следующим образом:

import { Input , Button , List } from 'antd'

Последний заключается в использовании компонента List.

<div style={{margin:'10px',width:'300px'}}>
    <List
        bordered
        dataSource={data}
        renderItem={item=>(<List.Item>{item}</List.Item>)}
    />    
</div>

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

import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'

const data=[
    '早8点开晨会,分配今天的开发工作',
    '早9点和项目经理作开发需求讨论会',
    '晚5:30对今日代码进行review'
]

class TodoList extends Component {
    render() { 
        return ( 
            <div style={{margin:'10px'}}>
                <div>
                    <Input placeholder='write someting' style={{ width:'250px', marginRight:'10px'}}/>
                    <Button type="primary">增加</Button>
                </div>
                <div style={{margin:'10px',width:'300px'}}>
                    <List
                        bordered
                        dataSource={data}
                        renderItem={item=>(<List.Item>{item}</List.Item>)}
                    />    
                </div>
            </div>
         );
    }
}
export default TodoList;

Суммировать: Этот класс в основном используетAnt DesignСделал интерфейс todoList и использовал<Input>,<Button>а также<List>компоненты, как этот курс преподаетсяRedux, поэтому использование этих компонентов не обсуждается, в основном для создания пользовательского интерфейса, чтобы подготовить почву для будущих курсов. если ты правAnt DesignОчень интересно, вы можете перейти на официальный сайт, чтобы прочитать документацию.

P05: Основы — Создание репозиториев в Redux — Store и Reducer

Этот раздел начинается, он официально введенReduxНа этапе кодирования вы также должны сосредоточиться на обучении. Прежде чем приступить к кодированию, вы должны ознакомиться с описанным ранее рабочим процессом редукции. Поэтому я также поместил картинку под текстом, чтобы облегчить вам предварительный просмотр. Как видно из картинки,ReduxРабочий процесс состоит из четырех частей, наиболее важной из которых являетсяstoreэта часть, потому что она помещает все данные вstoreв управлении. При написании кода важно сначала написатьstore.

Redux简化图

написать создатьstoreсклад

В использованииReduxПрежде необходимо использоватьnpm installДля установки откройте терминал, перейдите в каталог проекта и введите . (Если вы устанавливали его ранее, вам не нужно устанавливать его снова)

npm install --save redux

установленыreduxПосле этого вsrcсоздать каталогstoreпапку, затем создайтеindex.jsдокумент.

index.jsвесь проектstoreФайл, откройте файл, напишите следующий код.

import { createStore } from 'redux'  // 引入createStore方法
const store = createStore()          // 创建数据存储仓库
export default store                 //暴露出去

Таким образом, несмотря на то, что склад был создан, склад очень хаотичен. В настоящее время необходим модуль с возможностями управления. ЭтоReducers. Эти два должны создаваться вместе, чтобы не было взаимного конфликта на складе. существуетstoreВ папке создайте новый файлreducer.js, а затем напишите следующий код.

const defaultState = {}  //默认数据
export default (state = defaultState,action)=>{  //就是一个方法函数
    return state
}
  • state: информация о данных, которой необходимо управлять во всем проекте.У нас здесь нет данных, поэтому она представлена ​​пустым объектом.

такreducerУстанавливается, и редуктор вводится вstore, при повторном создании магазина он передается в магазин в виде параметра.

import { createStore } from 'redux'  //  引入createStore方法
import reducer from './reducer'    
const store = createStore(reducer) // 创建数据存储仓库
export default store   //暴露出去

Инициализировать данные для todoList в магазине

складstoreа такжеreducerВсе создано, можно инициализироватьtodoListданные в , вreducer.jsдокументdefaultStateВ объекте добавьте два свойства:inputValueа такжеlist. код показывает, как показано ниже

const defaultState = {
    inputValue : 'Write Something',
    list:[
        '早上4点起床,锻炼身体',
        '中午下班游泳一小时'
    ]
}
export default (state = defaultState,action)=>{
    return state
}

Это эквивалентно тому, что вы даетеStoreДобавлены два новых данных.

компоненты получаютstoreданные в

Со складом магазина и данными, как получить данные в строе? Сначала вы можете ввести store в компонент, который хотите использовать. Наш компонент todoList хочет использовать store, просто вsrc/TodoList.jsпапка для импорта. В это время ранее записанные данные данных могут быть удалены.

import store from './store/index'

Конечно, вы также можете сократить это так:

import store from './store'

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

constructor(props){
    super(props)
    console.log(store.getState())
}

В настоящее время данные не могут использоваться непосредственно компонентом на уровне пользовательского интерфейса, мы можем напрямую скопировать их в компонент.state, код выглядит следующим образом (я даю все код здесь для удобства обучения).

import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'
import store from './store'



class TodoList extends Component {
constructor(props){
    super(props)
    //关键代码-----------start
    this.state=store.getState();
    //关键代码-----------end
    console.log(this.state)
}
    render() { 
        return ( 
            <div style={{margin:'10px'}}>
                <div>
                    
                    <Input placeholder={this.state.inputValue} style={{ width:'250px', marginRight:'10px'}}/>
                    <Button type="primary">增加</Button>
                </div>
                <div style={{margin:'10px',width:'300px'}}>
                    <List
                        bordered
                        //关键代码-----------start
                        dataSource={this.state.list}
                        //关键代码-----------end
                        renderItem={item=>(<List.Item>{item}</List.Item>)}
                    />    
                </div>
            </div>
         );
    }
}
export default TodoList;

Выполнив описанные выше шаги, мы вынули данные из хранилища и использовали их в UI-интерфейсе компонента, что также является небольшим улучшением. В этом уроке мы говорили о том, как создатьstore,reduceи как использоватьstoreданные в . Знания в этом классе — это тоже суть редукционного мышления, и это тоже очень важно, вы можете выучить его еще дважды.

P06: Основы — установка Redux Dev Tools

В прошлом уроке было сделано хранилище состояний в Redux, также можно извлекать данные из хранилища. Далее нам нужно отладить данные в этих хранилищах в консоли, нам нужно использоватьRedux DevTools. Для его установки требуется научный доступ в Интернет, поэтому сначала вам нужно найти хорошую лестницу.

УстановитьRedux DevTools

я используюChromeУстановите плагин в браузере, в правом верхнем углу браузера есть три точки, затем нажмите «Дополнительные инструменты», затем нажмите «Расширения», затем нажмите «Открыть Интернет-магазин Chrome» справа, а затем выполните поиск дляRedux DevTools, вы можете увидеть следующий плагин, вы можете установить его напрямую.

ReduxDevTools

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

настроитьRedux Dev Tools

Это тоже вопрос, который мне часто задают мои друзья, то есть как настроить этотRedux Dev ToolsПлагин, на самом деле, был очень четко указан на веб-сайте, теперь откройте этот веб-сайт через плагин. Согласно подсказке веб-сайта, мы ставимindex.jsИзмените код, чтобы он выглядел следующим образом.

import { createStore } from 'redux'  //  引入createStore方法
import reducer from './reducer'    
const store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) // 创建数据存储仓库
export default store   //暴露出去

По сути, это предложение добавлено.

window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

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

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

Тогда этот класс будет здесь первым. В следующем классе мы продолжим учиться создаватьActionизменитьReduxвнутриStateценность .

P07: Основы — Испытайте процесс Redux через ввод

Этот урок о том, чтобы пройтиInputизменение, опытReduxОбщий процесс написания кода. Чего мы хотим добиться, так этоTodoListДемонстрация, пока значение в текстовом поле меняетсяreduxсерединаstoreЗначение , меняется соответственно, и по мереReduxсерединаstateКогда значение изменяется, компонент изменяется вместе с ним. Весь процесс - это картина, упомянутая ранее,

Redux简化图

Увеличить событие ответа ввода

Если хочешьInputИзменять,reduxтоже изменилось, надоInputдобавлены компонентыonChangeреагировать на события, Открытьsrcв каталогеToDolist.jsфайл, измените конкретный код следующим образом:

<Input 
    placeholder={this.state.inputValue} 
    style={{ width:'250px', marginRight:'10px'}}
    //---------关键代码----start
    onChange={this.changeInputValue}
    //---------关键代码----end
/>

После написания этого шага не забудьтеconstructorпровестиthisсвязывание, изменениеthisуказывает на.

constructor(props){
    super(props)
    this.state=store.getState();
    this.changeInputValue= this.changeInputValue.bind(this)
}

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

changeInputValue(e){
    console.log(e.target.value)
}

Затем откройте браузер и нажмитеF12Посмотрите на результаты в консоли. Вот весь текущий код:

import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'
import store from './store'



class TodoList extends Component {
    constructor(props){
        super(props)
        this.state=store.getState();
        this.changeInputValue= this.changeInputValue.bind(this)
    }
    render() { 
        return ( 
            <div style={{margin:'10px'}}>
                <div>
                    <Input 
                        placeholder={this.state.inputValue} 
                        style={{ width:'250px', marginRight:'10px'}}
                        onChange={this.changeInputValue}
                    />
                    <Button type="primary">增加</Button>
                </div>
                <div style={{margin:'10px',width:'300px'}}>
                    <List
                        bordered
                        dataSource={this.state.list}
                        renderItem={item=>(<List.Item>{item}</List.Item>)}
                    />    
                </div>
            </div>
         );
    }

    changeInputValue(e){
        console.log(e.target.value)
    }
}
export default TodoList;

Следующее, что нужно сделать, это изменитьReduxЗначение в, мы продолжаем учиться.

СоздайтеAction

хочу изменитьReduxвнутриStateзначение будет созданоAction. Действие — это объект. Этот объект обычно имеет два свойства.ActionОписание, второе значение для изменения.

changeInputValue(e){
    const action ={
        type:'change_input_value',
        value:e.target.value
    }
}

действие было создано, но черезdispatch()метод переданstore. Мы добавляем еще одну строку кода ниже действия.

changeInputValue(e){
    const action ={
        type:'changeInput',
        value:e.target.value
    }
    store.dispatch(action)
}

ЭтоActionбыл полностью создан иstoreСвязь есть.

storeавтоматическая стратегия продвижения

Впереди, конечно, я сказалstoreЭто просто склад, у него нет возможности управления, он получитactionавтоматически перенаправляется наReducer. Мы сейчас непосредственноReducerРаспечатайте результаты, чтобы увидеть. Открытьstoreпод папкойreducer.jsфайл, измените код.

export default (state = defaultState,action)=>{
    console.log(state,action)
    return state
}

Говоря об этом, мы можем объяснить два параметра:

  • state: относится к состоянию в исходном репозитории.
  • action: относится к недавно переданному состоянию действия.

Вы можете сказать, распечатав,ReducerТеперь, когда исходные данные и вновь переданные данные получены, нам нужно изменить значение в хранилище. Давайте сначала судитьtypeПравильно ли, если да, то нам нужно повторно объявить переменнуюnewState. (Помните: редюсер может только получать состояние, но не изменять его.), поэтому мы объявляем новую переменную, а затем используемreturnВернитесь.

export default (state = defaultState,action)=>{
    if(action.type === 'changeInput'){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    return state
}

обновить компонент

Теперь данные в магазине обновились, но компонент не обновился, нам нужно открыть файл компонентаTodoList.js,существуетconstructor, напишите следующий код.

constructor(props){
    super(props)
    this.state=store.getState();
    this.changeInputValue= this.changeInputValue.bind(this)
    //----------关键代码-----------start
    this.storeChange = this.storeChange.bind(this)  //转变this指向
    store.subscribe(this.storeChange) //订阅Redux的状态
    //----------关键代码-----------end
}

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

 storeChange(){
     this.setState(store.getState())
 }

Теперь, просмотрев в браузере, вы можете увидеть, что и компонент, и Redux изменились синхронно. Этот класс имеет много контента и проходит через процесс Redux.Если вы можете сделать этот класс самостоятельно, он считается введением в Redux. Вы можете просмотреть видео этого класса дважды, чтобы убедиться, что базовые знания прочны. Я действительно сказал от всего сердца, вы должны это сделать, иначе вы действительно не сможете этому научиться.

P08: Основы — Redux для создания списка ToDoList

Используя знания из предыдущего урока, мы используем тот же метод и процесс, чтобы снова разработать функцию списка в toDoList.В частности, при нажатии кнопки «Добавить» список компонента ToDoList будет увеличиваться. На самом деле у всех нас есть знания, но не хватает мастерства.

Напишите кнопки для добавления ответных событий и действий

Давайте сначала напишем событие ответа после нажатия кнопки, открываемTodoList.jsфайл, а затем добавьте его вместо кнопкиonClickСобытия, не забудьте связать.

<Button 
    type="primary"
    onClick={this.clickBtn}
>增加</Button>

затем вconstructorBinding, код выглядит следующим образом:

constructor(props){
    super(props)
    this.state=store.getState();
    this.changeInputValue= this.changeInputValue.bind(this)
    this.storeChange = this.storeChange.bind(this)
    //关键代码------------start----------
    this.clickBtn = this.clickBtn.bind(this)
    //关键代码------------end----------
    store.subscribe(this.storeChange) //订阅Redux的状态
}

После привязки можно написатьclickBtn()метод, здесь сначала замените бизнес-контент оператором печати.

clickBtn(){
    console.log('jspang.com')
}

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

Создайте действие и используйтеdispatch()Перейти кstore

существуетclickBtnДобавьте действие к методу, а затем используйтеdispatch()Метод передается в хранилище, и код выглядит следующим образом:

clickBtn(){
   const action = { type:'addItem'}
   store.dispatch(action)
}

На данный момент действие переданоstore, затем перейдите кReducerВы можете написать бизнес-логику в нем.

Напишите бизнес-логику редюсера

Открытьreducer.jsфайл, сначала напишите код, чтобы судитьtypeне так лиaddItem, если в список избыточности вставлено новое значение.

export default (state = defaultState,action)=>{
    if(action.type === 'changeInput'){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    //关键代码------------------start----------
    //state值只能传递,不能使用
    if(action.type === 'addItem' ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.push(newState.inputValue)  //push新的内容到列表中去
        newState.inputValue = ''
        return newState
    }
     //关键代码------------------end----------
    return state
}

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

P09: Основы — используйте Redux для реализации функции удаления ToDoList

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

Привяжите детей к реакции на события

Откройте каталог srcTodoList.jsфайл, затем найтиListкомпонентrenderItemсвойства, напишите код следующим образом:

<div style={{margin:'10px',width:'300px'}}>
    <List
        bordered
        dataSource={this.state.list}
        renderItem={(item,index)=>(<List.Item onClick={this.deleteItem.bind(this,index)}>{item}</List.Item>)}
    />    
</div>

тогда напиши этоdeleteItem()метод, помните, что он должен получитьindexпараметр.

deleteItem(index){
    console.log(index)
}

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

Написание действий Redux в методах

После написания метода привязки вы можете написатьactionТеперь при записи мы должны передать индекс в прошлое, код такой:

deleteItem(index){
    const action = {
        type:'deleteItem',
        index
    }
    store.dispatch(action)
}

Реализация бизнес-логики редуктора

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

if(action.type === 'deleteItem' ){ 
    let newState = JSON.parse(JSON.stringify(state)) 
    newState.list.splice(action.index,1)  //删除数组中对应的值
    return newState
}

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

P10: Основы — Советы по написанию Redux на работе — 1

надToDoList DemoЕсли вы освоили его, это означает, что вы начали работу с Redux, и вы можете сначала вознаградить себя. Но вы можете быть ветераном, который уже вышел на рабочее место, тогда вы пишете Redux немного ниже, вам нужно сделать разумное разделение, чтобы иерархия была более понятной. В этом и следующем уроке мы поговорим о двух маленьких хитростях в реальной разработке Redux.

Запись типов действий в один файл

НапишитеRedux Action, мы написали много дистрибутивов Action и сгенерировали многоAction Types,Если нужноActionгде мы сами называем одинTypeвозникают две основные проблемы:

  • Если эти типы не управляются единообразно, это не способствует использованию крупномасштабных проектов, а настройки будут генерировать избыточный код.
  • потому чтоActionвнутреннийType, необходимо сочетать сReducerвнутреннийtypeСоответствие один к одному, поэтому после того, как эта часть кода или буква написана неправильно, в браузере нет явной ошибки, что приносит большие трудности при отладке.

Тогда наш ЦК будетAction TypeВыделите отдельный файл. существуетsrc/storeПод папкой создайте новуюactionTypes.jsфайл, а затем централизованно поместите Type в файл для управления.

export const  CHANGE_INPUT = 'changeInput'
export const  ADD_ITEM = 'addItem'
export const  DELETE_ITEM = 'deleteItem'

Ввести в действие и использовать

написаноationType.jsфайл, который можно импортировать вTodoList.jsВ компоненте импортированный код выглядит следующим образом:

import { CHANGE_INPUT , ADD_ITEM , DELETE_ITEM } from './store/actionTypes'

После введения эти константы можно использовать в следующем коде вместо исходного.Typeстоило того.

changeInputValue(e){
    const action ={
        type:CHANGE_INPUT,
        value:e.target.value
    }
    store.dispatch(action)
}
clickBtn(){
    const action = { type:ADD_ITEM }
    store.dispatch(action)
}
deleteItem(index){
    const action = {  type:DELETE_ITEM, index}
    store.dispatch(action)
}

Внедрить Редуктор и внести изменения

также представлен первымactionType.jsфайл, а затем заменить соответствующую строку на константу, весь код выглядит следующим образом:

import {CHANGE_INPUT,ADD_ITEM,DELETE_ITEM} from './actionTypes'

const defaultState = {
    inputValue : 'Write Something',
    list:[
        '早上4点起床,锻炼身体',
        '中午下班游泳一小时'
    ]
}
export default (state = defaultState,action)=>{
    if(action.type === CHANGE_INPUT){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    //state值只能传递,不能使用
    if(action.type === ADD_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.push(newState.inputValue)  //push新的内容到列表中去
        newState.inputValue = ''
        return newState
    }
    if(action.type === DELETE_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.splice(action.index,1)  //push新的内容到列表中去
        return newState
    }
    return state
}

На этом разделение закончено, тогда вы можете спросить, у нас есть еще один файл, код выглядит более неясным, какой в ​​этом смысл? На самом деле, я сказал в начале курса, чтобы его можно было использовать.Например, добавляя, удаляя, изменяя и проверяя, нельзя использовать проверку один раз, и ее можно использовать во многих местах. Таким образом, мы можем напрямую импортировать файл для использования, что позволяет избежать избыточного кода. Кроме того, если мы напишем неправильное имя константы, программа сообщит об ошибке прямо в браузере и консоли, что может ускорить эффективность разработки и сократить время на поиск ошибок.

P11: Основы — Советы по написанию Redux на работе — 2

В этом классе мы продолжим рассматривать некоторые навыки оптимизации Redux в действии.После изучения основ мы будем постоянно совершенствовать наш режим написания, чтобы сделать наш код более подходящим для нужд разработки на уровне предприятия. Продолжайте совершенствоваться, вот дух, которым должен обладать мастер. На самом деле самый важный дух программистов — это дух мастерства, постоянно полирующий свой собственный код. В настоящее времяToDoListЭкшенов в компоненте много, и они разбросаны по разным частям программы.Если проект огромен, это неминуемо вызовет серьезную путаницу, то этот класс поставит всеRedux Actionв файл для управления.

записыватьactionCreators.jsдокумент

существует/src/storeПод папкой создайте файл сердцаactionCreators.js, сначала ввести запись предыдущего урока в файлactionTypes.jsдокумент.

import {CHANGE_INPUT}  from './actionTypes'

Доступно после импортаconstобъявить одинchangeInputActionПеременная, переменная - это функция стрелки, код выглядит следующим образом:

import {CHANGE_INPUT}  from './actionTypes'

export const changeInputAction = (value)=>({
    type:CHANGE_INPUT,
    value
})

Измените код в todoList

Когда у вас есть файл, вы можете поместитьactionCreatores.jsпознакомился сTodoLisitсередина.

import {changeInputAction} from './store/actionCreatores'

После импорта вы можете поставитьchangeInputValue()метод, измененный следующим образом.

changeInputValue(e){
        const action = changeInputAction(e.target.value)
        store.dispatch(action)
    }

Затем откройте программу в браузере и протестируйте ее, и она совершенно нормальна.

Измените два других метода действия.

Установите приведенный выше пример, измените два других метода,actionCreatores.jsПолный код выглядит следующим образом:

import {CHANGE_INPUT , ADD_ITEM,DELETE_ITEM}  from './actionTypes'

export const changeInputAction = (value)=>({
    type:CHANGE_INPUT,
    value
})

export const addItemAction = ()=>({
    type:ADD_ITEM
})

export const deleteItemAction = (index)=>({
    type:DELETE_ITEM,
    index
})


После записи этого файла вы можетеTodoList.jsВсе действия в файле заменены на прямой вызов методов. код показывает, как показано ниже:

import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'
import store from './store'
//关键代码-------------start
import {changeInputAction , addItemAction ,deleteItemAction} from './store/actionCreatores'
//关键代码------------end

class TodoList extends Component {
constructor(props){
    super(props)
    this.state=store.getState();
    this.changeInputValue= this.changeInputValue.bind(this)
    this.storeChange = this.storeChange.bind(this)
    this.clickBtn = this.clickBtn.bind(this)
    store.subscribe(this.storeChange) //订阅Redux的状态
}
    render() { 
        return ( 
            <div style={{margin:'10px'}}>
                <div>
                    <Input 
                        placeholder={this.state.inputValue} 
                        style={{ width:'250px', marginRight:'10px'}}
                        onChange={this.changeInputValue}
                        value={this.state.inputValue}
                    />
                    <Button 
                        type="primary"
                        onClick={this.clickBtn}
                    >增加</Button>
                </div>
                <div style={{margin:'10px',width:'300px'}}>
                    <List
                        bordered
                        dataSource={this.state.list}
                        renderItem={(item,index)=>(<List.Item onClick={this.deleteItem.bind(this,index)}>{item}</List.Item>)}
                    />    
                </div>
            </div>
         );
    }
    storeChange(){
        console.log('store changed')
        this.setState(store.getState())
    }
    //--------关键代码------start
    changeInputValue(e){
        const action = changeInputAction(e.target.value)
        store.dispatch(action)
    }
    clickBtn(){
        const action = addItemAction()
        store.dispatch(action)
    }
    deleteItem(index){
        const action = deleteItemAction(index)
        store.dispatch(action)
    }
    //--------关键代码------end
}
export default TodoList;

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

P12: Закуска — Redux заполняет три ямы

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

  • storeдолжен быть уникальным, множественнымstoreкатегорически не допускается, может быть только одинstoreпространство
  • Толькоstoreможет изменить их содержание,Reducerне может быть изменен
  • Reducerдолжна быть чистой функцией

StoreДолжно быть уникальным

СмотриTodoList.jsКод, как видите, вот такой/store/index.jsфайл, используется только в этом файлеcreateStore()метод, объявляет хранилище, которое затем используется всем приложениемstore. Ниже я даюindex.jsКонтент, который может помочь вам улучшить обзор.

import { createStore } from 'redux'  //  引入createStore方法
import reducer from './reducer'    
const store = createStore(
    reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) // 创建数据存储仓库
export default store   //暴露出去

Толькоstoreможет изменить их содержание,Reducerне может быть изменен

Многие друзья-новички подумают, что бизнес-логика написана наReducer, тот, который изменяет значение состояния, должен бытьReducer, на самом деле нет, в Reducer мы просто сделали возврат, вернулись кstore, никаких изменений не вносилось. Я также подчеркнул это в курсе выше. Давайте еще раз просмотрим код Reducer, чтобы углубить наше впечатление.

ReudcerПросто вернул измененные данные, но не изменилсяstoreданные в ,storeпонятноReducerданные и обновить себя.


import {CHANGE_INPUT,ADD_ITEM,DELETE_ITEM} from './actionTypes'

const defaultState = {
    inputValue : 'Write Something',
    list:[
        '早上4点起床,锻炼身体',
        '中午下班游泳一小时'
    ]
}
export default (state = defaultState,action)=>{
    if(action.type === CHANGE_INPUT){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    //state值只能传递,不能使用
    if(action.type === ADD_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.push(newState.inputValue)  //push新的内容到列表中去
        newState.inputValue = ''
        return newState
    }
    if(action.type === DELETE_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.splice(action.index,1)  //push新的内容到列表中去
        return newState
    }
    return state
}

Reducerдолжна быть чистой функцией

Давайте сначала посмотрим, что такое чистая функция, определение чистой функции:

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

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

export default (state = defaultState,action)=>{
    if(action.type === CHANGE_INPUT){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    //state值只能传递,不能使用
    if(action.type === ADD_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.push(newState.inputValue)  //push新的内容到列表中去
        newState.inputValue = ''
        return newState
    }
    if(action.type === DELETE_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.splice(action.index,1)  //push新的内容到列表中去
        return newState
    }
    return state
}

Его возвращаемый результат полностью определяется параметрами, переданными вstateа такжеaction决定的,这就是一个纯函数。这个在实际工作中是如何犯错的? например, вReducerДобавьте к нему асинхронную ajax-функцию, получите некоторые данные внутреннего интерфейса, а затем верните их, что не разрешено (включая использование вами функций даты), потому что это нарушает те же параметры вызова и возвращает то же правило чистой функции.

Далее я продолжу объяснять вамReduxПередовая часть г.ReduxИспользование видео более опытное и глубокое.Я технический толстяк, блогер, который делает бесплатные фронтальные видео, давайте работать вместе.

P13: Advanced — метод разделения пользовательского интерфейса компонента и бизнес-логики

Базовые знания Redux были изучены, но до мастерства вам еще далеко, а именно, как разделить часть пользовательского интерфейса и бизнес-логику, чтобы облегчить поддержку проекта. Вы можете спросить, есть ли какие-либо другие преимущества, кроме более простого обслуживания, и они определенно есть. Если его можно разделить, это означает, что больше людей могут сотрудничать для реализации разработки и быстрого запуска сверхкрупных проектов. Например, два человека пишут модуль одновременно, один пишет часть пользовательского интерфейса, другой пишет часть бизнес-логики, а затем эти два человека интегрируются вместе. Возможно, вы не думаете, что преимущества для небольших компаний очевидны, потому что финансовые ресурсы компании или отсутствие разработчиков сильно ограничивают этот метод разработки. Но у крупных компаний нет недостатка ни в деньгах, ни в людях, и все, что им нужно, это время.В настоящее время эта модель развития может решить проблему. Поэтому я настоятельно рекомендую вам идти в крупную компанию, хотя технология одна и та же, но модель развития крупной компании и маленькой компании совершенно разные. Немного не по теме, давайте перейдем к делу, посмотрим, как разделить UI и бизнес-логику компонента.

Разделить компоненты пользовательского интерфейса

можно увидетьTodoList.jsКомпоненты полностью связаны с пользовательским интерфейсом и бизнес-логикой.srcСоздайте новый файл в каталоге с именемTodoListUI.js, чтобы быстро создать базовую структуру страницы.

import React, { Component } from 'react';
class TodoListUi extends Component {
    
    render() { 
        return ( <div>123</div> );
    }
}
 
export default TodoListUi;

затем перейтиTodoList.jsреброJSXСкопируйте часть , и текущий код выглядит следующим образом (конечно, сейчас он недоступен, мы много чего не ввели, поэтому будет сообщено об ошибке):

import React, { Component } from 'react';
class TodoListUi extends Component {
    
    render() { 
        return ( 
            <div style={{margin:'10px'}}>
                <div>
                    <Input 
                        placeholder={this.state.inputValue} 
                        style={{ width:'250px', marginRight:'10px'}}
                        onChange={this.changeInputValue}
                        value={this.state.inputValue}
                    />
                    <Button 
                        type="primary"
                        onClick={this.clickBtn}
                    >增加</Button>
                </div>
                <div style={{margin:'10px',width:'300px'}}>
                    <List
                        bordered
                        dataSource={this.state.list}
                        renderItem={(item,index)=>(<List.Item onClick={this.deleteItem.bind(this,index)}>{item}</List.Item>)}
                    />    
                </div>
            </div>
         );
    }
}
 
export default TodoListUi;

Чтобы быть пригодным для использования, первым шагом является введениеantd, вы можете скопировать связанную библиотеку классовTodoList.jsСоответствующий код, поставитьantdИспользуемые CSS и компоненты копируются и импортируются.

import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'

но это неTodoListUI.jsтребуется компонентомstate(информация о состоянии), то вам нужно преобразовать родительский компонент, чтобы передать значение.

TodoList.jsмодификация файла

TodoList.jsтебе не нужно так многоJSXкод, просто импортируйтеTodoListUI.js.

import TodoListUI from './TodoListUI'

После вступления функцию рендеринга можно записать следующим образом.

render() { 
    return ( 
        <TodoListUI />
    );
}

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

Интеграция компонентов пользовательского интерфейса и компонентов бизнес-логики

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

Раздел рендеринга TodoList.js

render() { 
    return ( 
        <TodoListUI 
            inputValue={this.state.inputValue}
            list={this.state.list}
            changeInputValue={this.changeInputValue}
            clickBtn={this.clickBtn}
            deleteItem={this.deleteItem}
        />
    );
}

вам также нужноconstructor(в конструкторе) даdeleteItemметод перепривязкиthis, код показан ниже.

this.deleteItem = this.deleteItem.bind(this)

ИзмененоTodoList.jsфайл, а также заменить соответствующие свойства компонентов пользовательского интерфейса.Все коды следующие.

import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'
class TodoListUi extends Component {
    
    render() { 
        return ( 
            <div style={{margin:'10px'}}>
                <div>
                    <Input  
                        style={{ width:'250px', marginRight:'10px'}}
                        onChange={this.props.changeInputValue}
                        value={this.props.inputValue}
                    />
                    <Button 
                        type="primary"
                        onClick={this.props.clickBtn}
                    >增加</Button>
                </div>
                <div style={{margin:'10px',width:'300px'}}>
                    <List
                        bordered
                        dataSource={this.props.list}
                        renderItem={(item,index)=>(<List.Item onClick={(index)=>{this.props.deleteItem(index)}}>{item}</List.Item>)}
                    />    
                </div>
            </div>
         );
    }
}
 
export default TodoListUi;

Следует отметить, что вListФункция удаления компонента должна использовать форму функции стрелки вместо предыдущего метода и использовать метод атрибута в функции стрелки для вызова метода, который вы здесь нашли.

<List
    bordered
    dataSource={this.props.list}
    renderItem={(item,index)=>(<List.Item onClick={(index)=>{this.props.deleteItem(index)}}>{item}</List.Item>)}
/>    

После того, как все это сделано, вы уже разделили компоненты.На самом деле цель этого урока не этапы разделения, а идея разделения.Вы можете повторить его несколько раз, чтобы углубить разделение UI и бизнеса логика понять. Бесплатный курс по интерфейсу ищет технарей, увидимся на следующем занятии.

P14: Advanced — заполнение ям и компоненты без состояния в Redux

После написания программы на последнем занятии была небольшая ошибка, я ее тогда не заметил, мне ее подсказал друг в группе ВИП. В этом уроке мы сначала рассмотрим это наследие, а затем поговорим о компонентах без сохранения состояния. Компонент без состояния на самом деле является функцией, ему не нужно наследовать какой-либо класс (класс), конечно, как следует из названия, его не существуетstate(условие).因为无状态组件其实就是一个函数(方法),所以它的性能也比普通的ReactКомпоненты лучше.

Толстяк переворачивается и заполняет дырку

После написания UI и разделения бизнеса в последнем классе удалитеTodoList, есть ошибка, эта ошибка является ошибкой бизнес-логики, а не синтаксической ошибкой. То есть при удалении элементов нет проблем с удалением в положительном порядке, а вот с удалением в обратном порядке проблематично. В основном нашиindexЕсть проблема с переоформлением.

Исходный код ошибки был таким:

<List
    bordered
    dataSource={this.props.list}
    renderItem={(item,index)=>(<List.Item onClick={(index)=>{this.props.deleteItem(index)}}>{item}</List.Item>)}
/>   

Просто измените его на следующее, и это будет правильно.

 <List
    bordered
    dataSource={this.props.list}
    renderItem={
        (item,index)=>(
            <List.Item onClick={()=>{this.props.deleteItem(index)}}>
                {item}
            </List.Item>
        )
    }
/>    

Переписывание компонентов без состояния

Изменение компонентов пользовательского интерфейса на компоненты без состояния может повысить производительность программы.Давайте посмотрим, как их написать.

  1. Во-первых, нам больше не нужно внедрять React{ Component }, просто удалите его.
  2. потом немногоTodoListUIфункция, которая возвращает толькоJSXКак часть, этот шаг можно скопировать.
  3. функция передаетpropsпараметры, а затем изменить все внутренниеprops, Удалитьthis.

Вот код компонента без состояния после последней модификации, который более эффективен, чем обычные написанные ранееreactкомпоненты.

import React from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'

const TodoListUi = (props)=>{
    return(
        <div style={{margin:'10px'}}>
            <div>
                <Input  
                    style={{ width:'250px', marginRight:'10px'}}
                    onChange={props.changeInputValue}
                    value={props.inputValue}
                />
                <Button 
                    type="primary"
                    onClick={props.clickBtn}
                >增加</Button>
            </div>
            <div style={{margin:'10px',width:'300px'}}>
                <List
                    bordered
                    dataSource={props.list}
                    renderItem={
                        (item,index)=>(
                            <List.Item onClick={()=>{props.deleteItem(index)}}>
                                {item}
                            </List.Item>
                        )
                    }
                />    
            </div>
        </div>
    )
   
}

export default TodoListUi;

Резюме: Этот урок в основном учитReactКомпонент без сохранения состояния в , если это не было раньшеReduxВ то время добиться разделения было сложнее, но сейчас, когда мы работаем над проектом, мы должны подумать о том, можно ли сделать из компонента stateless-компонент. Если вы можете сделать компонент без состояния, попробуйте сделать его как компонент без состояния, ведь производительность намного выше.

P15: Advanced — Axios получает данные асинхронно и объединяется с Redux.

Этот класс - вопрос, который мои друзья задавали мне много в последние дни, то есть данные, полученные из внутреннего интерфейса, как я могу их поместить вReduxизstore, многие друзья застряли в этой трудности. В этом уроке мы научимся получать данные из фона иReduxВ сочетании для достижения желаемой бизнес-логики. Например, до того, как данные нашего списка находились вReducerЭто написано, этот класс используетAxiosПолучить данные из фона.

Создание фиктивных данных с помощью easy-mock

Об этом уже рассказывалось в базовом курсе, поэтому я не буду слишком подробно рассказывать об этом, если вы еще этого не знаете, просто прочитайте непосредственно базовый курс, повторять его неинтересно. Если вы скажете, что мне лень создавать новый, вы также можете использовать мои фиктивные данные, я дам адрес здесь.

адрес:Woohoo.easy-mock.com/mock/5 Если не гадать...

Базовый формат JSON, если вышеуказанный интерфейс не работает, можно использоватьEasy mockСделайте такой интерфейс сами:

{
  "data": {
    "list": [
      '早上4点起床,锻炼身体',
      '中午下班游泳一小时',
      '晚上8点到10点,学习两个小时'
    ]
  }
}

установить и использоватьAxios

Потому чтоReduxВ исследовании мы использовали новые проекты и директории, поэтому приходится переустанавливатьAxiosПлагины (ранее установленные не могут больше использоваться). Использовать напрямуюnpmустановить.

npm install --save axios

После завершения установки вы можетеTodoList.js, введены и использованы.

import axios from 'axios'

После введения, в функции цикла объявления компонентаcomponentDidMountПолучить данные удаленного интерфейса.

componentDidMount(){
    axios.get('https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList').then((res)=>{
        console.log(res)
    })
}

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

получить данные, а затемReduxОбъединить (ударение)

Полученные данные затем могут быть помещены вReduxизstoreВ середине эта часть такая же, как и предыдущие знания, я постараюсь дать код и поменьше говорить о теории. Сначала создайте функцию, откройте ранее написанноеstore/actionCreatores.jsфункцию, а затем напишите новую функцию со следующим кодом:

export const getListAction  = (data)=>({
    type:GET_LIST,
    data
})

В это время он покажет, что сохранение не может быть найдено.GET_LIST, мы идем вactionTypes.jsДобавьте константу в файл, а затем импортируйте ее вactionCreatores.jsсередина

export const  GET_LIST = 'getList'

познакомился сactionCreatores.jsсередина

import {CHANGE_INPUT , ADD_ITEM , DELETE_ITEM , GET_LIST}  from './actionTypes'

После этого шага вернитесь кTodoList.jsфайл, продолжайте писатьaxiosВ содержимом обратного вызова, прежде чем писать, не забудьте поставитьgetListActionИмпорт.

import {changeInputAction , addItemAction ,deleteItemAction,getListAction} from './store/actionCreatores'
componentDidMount(){
    axios.get('https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList').then((res)=>{    
        const data = res.data
        const action = getListAction(data)
        store.dispatch(action)
    })
}

Данные уже прошлиdispatchПерейти кstore, то вам нужноreducerОбработайте бизнес-логику. Открытьreducer.jsКод выглядит следующим образом (подробные шаги прокомментированы в коде):

//----关键代码--------start --------引入GET_LIST
import {CHANGE_INPUT,ADD_ITEM,DELETE_ITEM,GET_LIST} from './actionTypes'
//----关键代码--------end 
const defaultState = {
    inputValue : 'Write Something',
    //----关键代码--------start --------删除原来的初始化代码,减少冗余
    list:[]
}
export default (state = defaultState,action)=>{
    if(action.type === CHANGE_INPUT){
        let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
        newState.inputValue = action.value
        return newState
    }
    if(action.type === ADD_ITEM ){ 
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.push(newState.inputValue)  //push新的内容到列表中去
        newState.inputValue = ''
        return newState
    }
    if(action.type === DELETE_ITEM ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list.splice(action.index,1)  //push新的内容到列表中去
        return newState
    }
    //----关键代码--------start --------
    if(action.type === GET_LIST ){ //根据type值,编写业务逻辑
        let newState = JSON.parse(JSON.stringify(state)) 
        newState.list = action.data.data.list //复制性的List数组进去
        return newState
    }
    //----关键代码--------en'd --------

    return state
}

На этом процесс запроса данных из фона и объединения их с Redux завершается. Я надеюсь, что мои друзья смогут его практиковать.Наши программисты все больше похожи на настоящую разработку, и мои друзья должны продолжать знакомиться с этим режимом разработки на практике.

P16: Установка и настройка промежуточного программного обеспечения advanced-Redux-thunk

Изучая, выReduxОбладая всесторонним пониманием основного процесса, возможно, вы уже начали использовать его в своем проекте. На самом деле большую часть знаний о Redux мы изучили вместе, но я решил продолжить объяснятьRedux-thunkЭто наиболее часто используемый плагин для Redux. Когда этот плагин будет использоваться? например, вDispatchОдинActionПосле этого приезжайтеreducerРаньше для выполнения некоторых дополнительных операций нужно было использоватьmiddleware(промежуточное ПО). На практике вы можете использовать промежуточное программное обеспечение для ведения журналов, создания отчетов о сбоях, вызова асинхронных интерфейсов или маршрутизации. Это промежуточное ПО можно использовать сRedux-thunkЧтобы улучшить (конечно, вы можете использовать другие), это редуксdispatchВ этом уроке давайте сначала узнаем об установке и настройке (особенно о конфигурации, которую не удалось настроить многим небольшим партнерам).

Redux-thunk

УстановитьRedux-thunkкомпоненты

Redux-thunkне тамReduxв базовых компонентах, а это значит, что требуется новая установка. Установите и используйтеnpmВот и все.

npm install --save redux-thunk

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

настроитьRedux-thunkкомпоненты

Устанавливается легко, но нужно обратить внимание на настройку.Есть еще несколько мелких дыр.Если следовать официальной документации, то настройка будет неудачной. Его необходимо внедрить там, где создается магазинredux-thunk, для нашего каталога/store/index.jsдокумент.

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

import { createStore , applyMiddleware } from 'redux' 

2. Представьтеredux-thunkбиблиотека

import thunk from 'redux-thunk'

Если вы пишете по официальной документации, вы ставите преобразователь прямо вcreateStoreВторой параметр в порядке, но прежде чем мы настроилиRedux Dev Tools, который уже занимает второй параметр.

Метод, указанный в официальной документации:

const store = createStore(
    reducer,
    applyMiddleware(thunk)
) // 创建数据存储仓库

Совершенно нормально так писать, но нашRedux Dev ToolsПлагин нельзя использовать. Если вы хотите использовать оба одновременно, вам нужно использоватьФункция улучшения. Прежде чем использовать функцию добавления, ее необходимо сначала ввестиcompose.

import { createStore , applyMiddleware ,compose } from 'redux' 

затем используйтеcomposeСоздание функции расширения эквивалентно созданию функции цепочки.Код выглядит следующим образом:

const composeEnhancers =   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose

С помощью функции улучшения вы можете поместитьthunkОн добавлен для того, чтобы выполнялись обе функции.

const enhancer = composeEnhancers(applyMiddleware(thunk))

прямо в это времяcreateStoreВторой параметр в функции, используйте этотenhancerС переменными все в порядке, что эквивалентно выполнению обеих функций.

const store = createStore( reducer, enhancer) // 创建数据存储仓库

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

import { createStore , applyMiddleware ,compose } from 'redux'  //  引入createStore方法
import reducer from './reducer'    
import thunk from 'redux-thunk'

const composeEnhancers =   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose

const enhancer = composeEnhancers(applyMiddleware(thunk))

const store = createStore( reducer, enhancer) // 创建数据存储仓库
export default store   //暴露出去

Даже еслиReduxПромежуточное программное обеспечение настроено, вы можете запустить проект, зайти в браузер, чтобы увидеть результаты и посмотретьRedux Dev Toolsплагин тоже.

P17: Как использовать advanced-Redux-thunk

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

существуетactionCreators.jsНапишите бизнес-логику в

доactionCreators.jsВсе они являются определенными действиями, и нет возможности написать бизнес-логику.Redux-thunkПосле этого можно поставитьTodoList.jsсерединаcomponentDidMountЗдесь написана бизнес-логика. То есть поместите код, который запрашивает данные из фона, вactionCreators.jsв файле. Затем нам нужно импортироватьaxiosи напишите новый метод функции. (Предыдущее действие было объектом, а теперь действие может быть функцией, т.е.redux-thunkпреимущества)

import axios from 'axios'
...something...
export const getTodoList = () =>{
    return ()=>{
        axios.get('https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList').then((res)=>{
            const data = res.data
            console.log(data)
        })
    }
}

Теперь нам нужно выполнить этот метод и просмотреть результаты в консоли, которые в это время можно модифицировать.TodoList.jsв файлеcomponentDidMountкод.

//先引入getTodoList
import {getTodoList , changeInputAction , addItemAction ,deleteItemAction,getListAction} from './store/actionCreatores'
---something---
componentDidMount(){
    const action = getTodoList()
    store.dispatch(action)
}

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

export const getTodoList = () =>{
    return (dispatch)=>{
        axios.get('https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList').then((res)=>{
            const data = res.data
            const action = getListAction(data)
            dispatch(action)
            
        })
    }
}

Эта функция может быть передана напрямуюdispatchвойдите, это автоматически, тогда мы просто используемdispatch(action)Просто передайте это. Теперь мы можем открыть браузер для проверки.

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

Может быть, вы думаете, что писать такие программы очень запутанно. На самом деле, я тоже так думал, когда впервые начал писать Redux, но по мере того, как проект становится все больше и больше, вы обнаружите, что совместное использованиеstateпоместите бизнес-логику в свойReduxПодсказки очень правильные, это сделает вашу программу более организованной. При автоматизированном тестировании метод можно протестировать напрямую, но сложно протестировать жизненный цикл. Все крупные компании, с которыми я в настоящее время общаюсь, требуют, чтобы это было написано таким образом.Если вы все еще не можете понять преимущества, не беспокойтесь об этом, просто сначала напишите это в этой форме. После того, как вы напишете 2-3 проекта, вы поймете преимущества этого стиля письма.

P18: установка и настройка Advanced-Redux-saga

Сначала позвольте мне объяснить, что промежуточное программное обеспечение, о котором мы здесь говорим, неReactпромежуточное ПО, ноReduxMiddleware, вы должны это понимать, иначе будут большие проблемы в работе, вашиReactСтруктура знаний также может быть предвзятой. фактическиReduxпромежуточное ПО не толькоRedux-thunk, и еще один известныйRedux-sagaКонечно, это промежуточное ПО не используется нашей компанией, а только исследуется нами, поэтому в объяснении могут быть некоторые недостатки. В настоящее время отечественные ИТ-компании в основном используют эти два промежуточных ПО, и мало других используется.Это как Coca-Cola и Pepsi, так что надо учиться.

Установка редукс-саги

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

npm install --save redux-saga

Адрес github указан здесь, чтобы вы могли лучше изучить.

GitHub.com/dip-galvanizing-saga/…

импортировать и создаватьRedux-saga

После установки вы можете использовать его непосредственно в/src/store/index.jsвведен вredux-sagaи создайтеsagaMiddleware, код показан ниже:

import createSagaMiddleware from 'redux-saga'   //引入saga
const sagaMiddleware = createSagaMiddleware();   //创建saga中间件

После того, как он создан, он все еще проходит через функцию улучшения Redux. то есть оригиналRedux-thunkзаменитьsagaПромежуточное ПО (обратите внимание на удаление исходного неиспользуемогоredux-thunkимпорт).

import { createStore , applyMiddleware ,compose } from 'redux'  //  引入createStore方法
import reducer from './reducer'   
//------关键代码----start----------- 
import createSagaMiddleware from 'redux-saga' 
const sagaMiddleware = createSagaMiddleware();
//------关键代码----end-----------

const composeEnhancers =   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose
//------关键代码----start-----------
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware))
//------关键代码----end-----------

const store = createStore( reducer, enhancer) // 创建数据存储仓库
export default store   //暴露出去

После завершения этого шага исходныйredux-thunkзаменитьredux-sagaКонечно, мы не можем использовать его сейчас, нам нужно еще продолжить настройкуsagas.jsдокумент.

Создайтеsagas.jsфайл и импорт

redux-sagaЯ надеюсь, вы напишете бизнес-логику в отдельный файл, здесь мы находимся в/src/store/создать папкуsagas.jsдокумент.

function* mySaga() {} 
export default mySaga;

После создания он напрямую импортируется вindex.jsвнутри.

import mySagas from './sagas' 

Затем выполните метод запуска, пустьsagaи работает.

sagaMiddleware.run(mySagas)

Для вашего удобства здесь/src/store/index.jsвсего содержания.

import { createStore , applyMiddleware ,compose } from 'redux'  //  引入createStore方法
import reducer from './reducer'   
import createSagaMiddleware from 'redux-saga' 
import mySagas from './sagas' 

const sagaMiddleware = createSagaMiddleware();

const composeEnhancers =   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware))
const store = createStore( reducer, enhancer) 
sagaMiddleware.run(mySagas)


export default store  

В настоящее время он полностью заменен наredux-saga, так что передTodoList.jsКод необходимо удалить, иначе будет сообщено об ошибке. Основное удалениеcomponentDidMountОбъявите код в периодической функции. такredux-sagaПосле завершения установки и настройки мы можем написать промежуточное ПО. На самом деле, эту настройку вообще нужно сделать только один раз в проекте, вы можете полностью добавить веб-страницу в закладки, а потом вернуться и просмотреть ее, когда она вам понадобится.

P19: Advanced — Получите TodoList с помощью Redux-saga

Последний класс пройденredux-sagaустановка и базовая настройка, в этой статье используетсяRedux-sagaЧтобы завершить приобретение списка TodoList. фактическиredxu-sagaчемredux-thunkЧтобы быть более сложным, ему нужно изучить гораздо больше API, по крайней мере, стоимость обучения увеличилась. Но некоторые люди говорятsagaОн больше подходит для масштабных проектов.Я не буду делать заявление, и не хочу начинать войну.Если ваша компания используетsaga, этих двух статей достаточно, чтобы начать. Без дальнейших церемоний, давайте продолжим учиться.

записыватьTodoList.jsдокумент

Давайте сначала преобразимсяTodoList.jsфайл, сейчасcomponentDidMountВнутри пусто, поэтому нам предстоит выполнить базовые операции редукса.Я больше не буду вводить этот процесс.Я практиковал его более 10 раз.

Конечно, вы можете представитьaction, конечно, это действие еще не написано, мы его напишем позже, и назовемgetMyListAction(Вы можете назвать его любым именем, просто запомните его, потому что мы продолжим использовать его ниже)

import {getMyListAction, changeInputAction , addItemAction ,deleteItemAction} from './store/actionCreatores'

Тогда следите за трендомactionCreators.jsЭто действие создается в файле.

export const getMyListAction = ()=>({
    type:GET_MY_LIST
})

После написания вы найдетеGET_MY_LISTНет, его нужно сначала ввести, а потомactionTypes.jsопределить в

import {GET_MY_LIST,CHANGE_INPUT , ADD_ITEM,DELETE_ITEM,GET_LIST}  from './actionTypes'

Определение файла actionTypes.jsGET_MY_LIST

export const  GET_MY_LIST = 'getMyList'

затем вы можете вернуться кTodoList.jsфайл, пишиcomponentDidMountсодержание в.

componentDidMount(){
    const action =getMyListAction()
    store.dispatch(action)
    console.log(action)
}

Тест завершен и может быть удаленconsole.log(), сохраняйте код кратким и без избыточного кода.

Написать файл sagas.js (также бизнес-логику)

использоватьsagaБизнес-логика промежуточного программного обеспечения написана в этомsagas.jsВ файле, в файле мы используемmySagaв качестве входной функции. Захват переданной функции в функции входаactionТип, в зависимости от типа вызываются разные методы.

import { takeEvery } from 'redux-saga/effects'  
import {GET_MY_LIST} from './actionTypes'

//generator函数
function* mySaga() {
    //等待捕获action
    yield takeEvery(GET_MY_LIST, getList)
}

function* getList(){
    console.log('jspang')
}
  
export default mySaga;

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

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

import { takeEvery ,put } from 'redux-saga/effects'  
import {GET_MY_LIST} from './actionTypes'
import {getListAction} from './actionCreatores'
import axios from 'axios'

//generator函数
function* mySaga() {
    //等待捕获action
    yield takeEvery(GET_MY_LIST, getList)
}

function* getList(){
    //这段代码我就不删除了。
    // axios.get('https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList').then((res)=>{
    //     const data = res.data
    //     const action = getListAction(data)
    //     put(action)
        
    // })
    const res = yield axios.get('https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList')
    const action = getListAction(res.data)
    yield put(action)
}
  
export default mySaga;

Резюме: этоRedux-sagaНа самом деле у саги есть и другие API, но я не использую их в своей работе, поэтому могу гарантировать только начальный уровень, а что касается углубления, то вы можете изучить его самостоятельно. Что касаетсяredux-thunkа такжеredux-sagaСпоры о том, какой из них лучше, не ведутся, как гласит популярная в Интернете пословица, только дети задают вопросы с несколькими вариантами ответов, и этому учатся все ветераны техники.

P20: Введение и установка Advanced-React-Redux

React-ReduxЭто часто используемый компонент в экосистеме React, он может упроститьReduxПроцесс, в этом уроке мы воссоздадим проектDemo02, а затем провести несколько уроков сReact-reduxпоставить предыдущийTodoListДело переосуществляется снова. Если ваша компания не использует этот плагин, вам не нужно тратить время на его изучение. Но в качестве статьи знания должны быть максимально полными. (обратите внимание на концепции: React, Redux, React-redux — это три разные вещи)

ReactИнициализация проекта

Поскольку строительные леса были установлены раньшеcreat-react-app, так что теперь введите следующую команду прямо в терминале проекта.

create-react-app demo02
cd demo02
npm start

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

react-redux课程

После завершения установки удалите некоторые ненужные стили и коды, в/srcВ каталоге только одинindex.jsфайлы, а все остальные удаляются.В это время проект запустить уже нельзя, что нормально.

import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));

Установитьreact-redux

После инициализации проекта используйте его напрямуюnpmУстановить из командной строкиReact-redux, время установки для этой сети различается.

npm install --save react-redux

Версия, установленная во время записи видео,7.1.0Версия может отличаться от моей, когда вы учитесь, если есть разница, вы можете проверить последнюю документацию по API на Github.

Измените код, чтобы он работал

В настоящее время проект все еще не может быть запущен, и необходимо построитьTodoList.jsс компонент. Код проекта выглядит следующим образом:

import React, { Component } from 'react';
class TodoList extends Component {
    render() { 
        return ( <div>JSPang</div> );
    }
}
export default TodoList;

имеютTodoList.jsПосле этого вводим вindex.jsфайл, а затем измените код следующим образом:

import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList'
ReactDOM.render(<TodoList />, document.getElementById('root'));

В это время снова просмотрите его в браузере, и будет выведен только один вывод.JSPangшрифт. Это некрасиво, но проект уже запущен. Далее пишемrenderСтраница JSX в работе (чтобы сэкономить время, она больше не используетсяantd).

render() { 
    return (
        <div>
            <div><input /><button>提交</button></div>
            <ul>
                <li>JSPang</li>
            </ul>
        </div>
        );
}

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

ReduxУстановка и использование (обзор)

Сначала установить в терминалReduxПакет, поскольку это новый проект, необходимо переустановить.

npm install --save redux

Сначала создайтеstoreпапка, в/storeсоздать следующийindex.jsфайл и напишите следующий код:

import {createStore} from 'redux'
import reducer from './reducer'

const store = createStore(reducer)

export default store

В настоящее время у нас нетreducer, поэтому мы хотим создатьreducer.jsфайл, код такой:

const defalutState = {
    inputValue : 'jspang',
    list :[]
}

export default (state = defalutState,action) =>{
    return state
}

после этогоTodoList.jsконструктор вconstructorиспользуется в.

import React, { Component } from 'react';
//-----关键代码--------start
import store from './store'
//-----关键代码--------end
class TodoList extends Component {
    //-----关键代码--------start
    constructor(props){
        super(props)
        this.state = store.getState()
    }
    //-----关键代码--------end
    render() { 
        return (
            <div>
                <div>
                    //-----关键代码--------start
                    <input value={this.state.inputValue} />
                    //-----关键代码--------end
                    <button>提交</button>
                </div>
                <ul>
                    <li>JSPang</li>
                </ul>
            </div>
            );
    }
}
 
export default TodoList;

Написав этот абзац, сохраните его в браузере и посмотрите, у вас должно получитьсяstoreзначение в , до сих пор мы только что установилиReact-Redux, но он еще не использовался.Этот класс посвящен только настройке базовой среды и повторению предыдущих знаний. Следующий урок мы будем изучать шаг за шагомReact-ReduxНе беспокойтесь о знаниях, друзья, давайте сначала настроим среду разработки.

P21: Advanced — провайдер и подключение в React-redux

Последний класс пройденReact-reduxразвиватьTodoListБазовая среда для компонента. Получайте удовольствие от обучения сейчасReact-reduxНу, этот урок в основном для изученияProviderа такжеconnectЭти две точки знания.

<Provider>Объяснение поставщика

<Provider>Это поставщик, пока используется этот компонент, можно использовать все остальные компоненты компонента.storeДа, это тожеReact-reduxосновные компоненты. имеют<Provider>ты можешь поставить/src/index.jsПерепишите его в следующем стиле кода, конкретное объяснение представлено в видео.

import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList'
//---------关键代码--------start
import { Provider } from 'react-redux'
import store from './store'
//声明一个App组件,然后这个组件用Provider进行包裹。
const App = (
   <Provider store={store}>
       <TodoList />
   </Provider>
)
//---------关键代码--------end
ReactDOM.render(App, document.getElementById('root'));

После написания этого мы идем в браузер, чтобы просмотреть его, и обнаруживаем, что код также может работать идеально. Следует отметить, что традиционный метод до сих пор используется для полученияstoreданные в . имеютProviderВосстановить данные не так уж и сложно.

connectИспользование разъемов

Как легко получитьstoreКитайские данные? открыть первымTodoList.jsфайл, импортconnect, это коннектор (по сути это метод), с помощью этого коннектора можно легко получить данные.

import {connect} from 'react-redux'  //引入连接器

В это время то, что подвергается воздействию, становитсяconnect, код выглядит следующим образом.

export default connect(xxx,null)(TodoList);

здесьxxxПредставляет отношение сопоставления, которое еще не было создано.

Производство картографических отношений

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

const stateToProps = (state)=>{
    return {
        inputValue : state.inputValue
    }
}

Затем поместитеxxxизменить наstateToProps

export default connect(stateToProps,null)(TodoList)

тогда поставь<input>внутреннийstateярлык, изменить наprops, код показан ниже:

 <input value={this.props.inputValue} />

Для того, чтобы облегчить ваше изучение, я даю всеTodoList.jsВсе код.

import React, { Component } from 'react';
import store from './store'
import {connect} from 'react-redux'

class TodoList extends Component {
    constructor(props){
        super(props)
        this.state = store.getState()
    }
    render() { 
        return (
            <div>
                <div>
                    <input value={this.props.inputValue} />
                    <button>提交</button>
                </div>
                <ul>
                    <li>JSPang</li>
                </ul>
            </div>
            );
    }
}

const stateToProps = (state)=>{
    return {
        inputValue : state.inputValue
    }
}
 
export default connect(stateToProps,null)(TodoList);

Написав его, перейдите в браузер и проверьте его, и вы обнаружите, что наша сопоставленная связь также доступна. Этот классReact-ReduxКлючевые моменты использования плагинов нужно написать несколько раз и помнить об этом процессе. Приходите сюда первым, мы продолжим реализовывать это в следующем классеTodoListкомпоненты.

P22: Модификация данных Advanced-React-redux

Доступен в последнем классеReact-reduxПолучите успешноStoreв данных. Этот урок учит, как изменитьStoreданные в . То есть, когда мы модифицируем<input>изменить значение вstoreДанные, интерфейс пользовательского интерфейса также меняются соответственно.

записыватьonChangeреагировать на события

ОткрытьTodoList.jsфайл, затем в<button>зарегистрироваться наonChangeСобытия, тут я поленюсь и привяжу напрямуюthis.

 <input value={this.props.inputValue} onChange={this.inputChange.bind(this)} />

С событием нужно написать соответствующий метод, вот самый простойinputChangeметод.

inputChange(e){
    console.log(e.target.value)
}

Тогда ошибок в консоли в браузере больше не будет, и значение можно будет распечатать при вводе, и наша привязка названия книги пройдет успешно. После этого шага нам нужно изменить наreact-redux.

записыватьDispatchToProps

нужно использоватьreact-redux, мы можем написать другое отображениеDispatchToProps, сначала посмотрите на следующий код, вы обнаружите, что есть два параметра, второй параметр, который мы используем, этоnull.

export default connect(stateToProps,null)(TodoList);

DispatchToPropsЭто второй передаваемый параметр, через который параметр можно изменить.storeзначение в .

const dispatchToProps = (dispatch) =>{
    return {
        inputChange(e){
            console.log(e.target.value)
        }
    }
}

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

 <input value={this.props.inputValue} onChange={this.props.inputChange} />

Затем передайте второй параметр подключения.

export default connect(stateToProps,dispatchToProps)(TodoList);

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

import React, { Component } from 'react';
import store from './store'
import {connect} from 'react-redux'

class TodoList extends Component {
    constructor(props){
        super(props)
        this.state = store.getState()
    }
    render() { 
        return (
            <div>
                <div>
                    <input value={this.props.inputValue} onChange={this.props.inputChange} />
                    <button>提交</button>
                </div>
                <ul>
                    <li>JSPang</li>
                </ul>
            </div>
            );
    }
}
const stateToProps = (state)=>{
    return {
        inputValue : state.inputValue
    }
}

const dispatchToProps = (dispatch) =>{
    return {
        inputChange(e){
            console.log(e.target.value)
        }
    }
}
 
export default connect(stateToProps,dispatchToProps)(TodoList);

распределятьactionв магазин

Отношение сопоставления выполнено, и следующим шагом является выполнениеactionраспространение иreducerДостаточно написать бизнес-логику. Диспетчерское действие такое же, как и в предыдущем процессе, поэтому я приведу код напрямую.

const dispatchToProps = (dispatch) =>{
    return {
        inputChange(e){
            let action = {
                type:'change_input',
                value:e.target.value
            }
            dispatch(action)
        }
    }
}

После отправки требуется вreducerВнутри пропишите соответствующую бизнес-логику.

const defalutState = {
    inputValue : 'jspang',
    list :[]
}
export default (state = defalutState,action) =>{
    if(action.type === 'change_input'){
        let newState = JSON.parse(JSON.stringify(state))
        newState.inputValue = action.value
        return newState
    }
    return state
}

Таким образом, даже если весь процесс модификации завершен, проверьте его в браузере, и эффект изменения поля ввода должен быть достигнут. Этот процесс может сбивать с толку, когда вы впервые его изучаете, но если вы будете заниматься им больше, вы обнаружите, что он очень прост, это шаблон, и это снизит вероятность ошибок программы. Рекомендуется написать этот процесс не менее 5 раз, насколько я знаю, почти все компании используют react-redux, так что этот процесс не менее важен, чемReduxпроцесс должен быть освоен.

P23: Advanced-React-redux добавляет данные списка

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

Дать<button>кнопка для добавления события клика

прямо в/src/TodoList.jsвнутреннийButtonдобавить одинonClickсобытие, код выглядит следующим образом:

<button onClick={this.props.clickButton}>提交</button>

Обратите внимание, что он все еще используется здесьprops, то есть вам также нужно написать метод вdispatchToPropsвнутри. Давайте напишем здесь тест, чтобы увидеть, привязано ли оно.

const dispatchToProps = (dispatch) =>{
    return {
        inputChange(e){
            let action = {
                type:'change_input',
                value:e.target.value
            }
            dispatch(action)
        },
        clickButton(){
            console.log('111111111')
        }
    }
}
 

законченныйclickButtonПосле метода просмотрите его в браузере, откройте консоль браузера, чтобы увидеть результат, вы должны увидеть отображение при нажатии111111111. Этот шаг завершен, просто используйтеdispatchраспределятьaction.

clickButton(){
    let action = { type:'add_item' }
    dispatch(action)
}

записыватьReducerбизнес-логика

После того, как распределение будет завершено,ReducerНапишите бизнес-логику, этот шаг в основном такой же, как и операция вместе.

const defalutState = {
    inputValue : 'jspang',
    list :[]
}

export default (state = defalutState,action) =>{
    if(action.type === 'change_input'){
        let newState = JSON.parse(JSON.stringify(state))
        newState.inputValue = action.value
        return newState
    }
    //----关键代码------start---------
    if(action.type === 'add_item'){
        let newState = JSON.parse(JSON.stringify(state))
        newState.list.push(newState.inputValue)
        newState.inputValue = ''
        return newState
    }
    //----关键代码------end---------
    return state
}

Создание UI части страницы

После этого шага переходим кTodoList.jsв ходе выполненияJSXЧасть написания, прежде чем писать, нужноstateToPropsОтношение отображения выполнено.

const stateToProps = (state)=>{
    return {
        inputValue : state.inputValue,
        list:state.list
    }
}

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

<ul>
    {
        this.props.list.map((item,index)=>{
            return (<li key={index}>{item}</li>)
        })
    }
</ul>

Этим достигается увеличениеTodoListэлементы списка, приведенные здесьTodoList.jsКод прост в освоении и использовании.

import React, { Component } from 'react';
import store from './store'
import {connect} from 'react-redux'

class TodoList extends Component {
    constructor(props){
        super(props)
        this.state = store.getState()
    }
    render() { 
        return (
            <div>
                <div>
                    <input value={this.props.inputValue} onChange={this.props.inputChange} />
                    <button onClick={this.props.clickButton}>提交</button>
                </div>
                <ul>
                    {
                        this.props.list.map((item,index)=>{
                            return (<li key={index}>{item}</li>)
                        })
                    }
                </ul>
            </div>
        );
    }
}
const stateToProps = (state)=>{
    return {
        inputValue : state.inputValue,
        list:state.list
    }
}

const dispatchToProps = (dispatch) =>{
    return {
        inputChange(e){
            let action = {
                type:'change_input',
                value:e.target.value
            }
            dispatch(action)
        },
        clickButton(){
            let action = {
                type:'add_item'
            }
            dispatch(action)
        }
    }
}
export default connect(stateToProps,dispatchToProps)(TodoList);

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

P24: Оптимизация программы Snack-React-redux (конец)

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

Скопируйте код со структурами

Теперь в коде есть несколько местthis.propsЭто все повторяется, и вы можете использовать его в это времяjavascriptМетод присваивания деконструкции для оптимизации кода. ИсправлятьTodoList.jsсерединаRenderфункции, измените исходный код на следующий код:

    render() { 
        let {inputValue ,inputChange,clickButton,list} = this.props;
        return (
            <div>
                <div>
                    <input value={inputValue} onChange={inputChange} />
                    <button onClick={clickButton}>提交</button>
                </div>
                <ul>
                    {
                        list.map((item,index)=>{
                            return (<li key={index}>{item}</li>)
                        })
                    }
                </ul>
            </div>
        );
    }

ПучокTodoListИзменен на компонент пользовательского интерфейса - улучшена производительность

Как видите, сейчасTodoListВ компоненте нет бизнес-логики, только однаRenderметод, вы можете изменить его на компонент пользовательского интерфейса (компонент без сохранения состояния) в это время.Компонент пользовательского интерфейса — это метод, который уменьшает количество избыточных операций, тем самым улучшая производительность программы. Теперь повторно объявитьTodoListпеременную, а затем скопируйте содержимое функции рендеринга.Небольшими изменениями вы можете получить следующий код:

const TodoList =(props)=>{
    let {inputValue ,inputChange,clickButton,list} = props; // 粘贴过来后,此处要进行修改
    return (
        <div>
            <div>
                <input value={inputValue} onChange={inputChange} />
                <button onClick={clickButton}>提交</button>
            </div>
            <ul>
                {
                    list.map((item,index)=>{
                        return (<li key={index}>{item}</li>)
                    })
                }
            </ul>
        </div>
    );
}

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

import React from 'react';
import {connect} from 'react-redux'

Для лучшего обучения я даю текущийTodoList.jsвсех кодов.

import React from 'react';
import {connect} from 'react-redux'


const TodoList =(props)=>{
    let {inputValue ,inputChange,clickButton,list} = props; // 粘贴过来后,此处要进行修改
    return (
        <div>
            <div>
                <input value={inputValue} onChange={inputChange} />
                <button onClick={clickButton}>提交</button>
            </div>
            <ul>
                {
                    list.map((item,index)=>{
                        return (<li key={index}>{item}</li>)
                    })
                }
            </ul>
        </div>
    );
}


const stateToProps = (state)=>{
    return {
        inputValue : state.inputValue,
        list:state.list
    }
}

const dispatchToProps = (dispatch) =>{
    return {
        inputChange(e){
            let action = {
                type:'change_input',
                value:e.target.value
            }
            dispatch(action)
        },
        clickButton(){
            let action = {
                type:'add_item'
            }
            dispatch(action)
        }
    }
}
export default connect(stateToProps,dispatchToProps)(TodoList);

Тогда давайте перевернем его и поймем смысл последнего предложения кода.

export default connect(stateToProps,dispatchToProps)(TodoList);

connectФункция состоит в том, чтобы разделить компоненты пользовательского интерфейса (компоненты без сохранения состояния) и код бизнес-логики, а затем связать их вместе с помощью подключения, чтобы сделать код более понятным и простым в обслуживании. Это тожеReact-ReduxСамая большая точка.

ReduxУчебники и видео здесь, я объясню следующий набор курсовReact-router, следите за блогом, чтобы не пропустить последние обучающие видео.