Я использовал Vue и сейчас реагирую так же.
Я выучил Vue + Vuex перед реагированием. У меня было ощущение, что redux будет очень похож на Vuex. Но я вскоре понял, что это не так прямое, как Vuex, и это делает вещи по-разному (хотя оба вдохновлены из архитектуры потока).
Это естественная тенденция к сравнению с функциями одной структуры к ранее изученной структуре или библиотеке, изучая новую. Это дает простой способ понять и помнить, потому что мы знаем, как это работает в другом.
Так вот статью о сравнении о том, как Vuex и Redux делают то же самое по-разному.
Примечание. Я не сравниваю основные рамки, я концентрируюсь только по признакам Vuex и Redux Отказ
HTML
Разметка обоих приложений на сегодняшний день на сегодняшний день на сегодняшний день мы будем использовать директивы в функциях Vue и рендеринга в реагировании на их изменение.
TO DO LIST
Начиная
Давайте сначала покажем вам, как начать использовать эти государственные библиотеки управления и их основной код BoverPlate.
Вариант
Vuex тесно связан с Vuejs, следовательно, есть меньший код котельной для Vuex для начала.
import Vue from 'vue' import App from './App.vue' import store from './store' import './main.css'; Vue.config.productionTip = false new Vue({ store, render: h => h(App) }).$mount('#app')
Redux.
Redux является Framework Agnostic, он не специфичен для реагирования. Следовательно, нам нужно импортировать несколько других библиотек для его работы.
import React from 'react'; import ReactDOM from 'react-dom'; import App from './components/App'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import reducer from './reducers'; const store = createStore( reducer ); ReactDOM.render(, document.getElementById('root'));
Магазин и штат
И VEUX и Redux имеют один объект магазина, который поддерживает все переменные состояния приложения, давайте посмотрим, как создавать переменные состояния в магазине.
Как Vuex это делает
Состояние Vuex является смежным, поэтому мы можем напрямую создавать переменные состояния и назначить их значениям.
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex) export default new Vuex.Store({ state: { todos: [] } });
Как redux делает это
Redux использует Редукторы, которые являются чистыми функциями, которые принимают предыдущее состояние и действие и возврат следующего состояния. Мы поговорим больше об этом ниже.
var initialState = []; const todos = (state = initialState, action) => { }; export default todos;
Redux использует редукторы для создания и управления набором состояний.
Используя эти состояния в нашем приложении
Теперь, когда мы смогли создать состояние с одним предметом Todo Hardcoded, давайте посмотрим, как мы можем использовать это в нашем приложении.
Как Vuex это делает
Vue имеет mapstate ()
Функция помощника для сопоставления состояний из нашего магазина Vuex на наши компоненты. Эти соположенные переменные затем могут быть доступны непосредственно как обычные переменные состояния, хотя мы не можем изменять эти переменные напрямую.
//app.vue
//store.js export default new Vuex.Store({ state: { todos: [] }, getters: { completedList(state) { return state.todos.filter(todos => todos.completed === true); } } })
Если нам нужно выполнить некоторую операцию в наших переменных нашего состояния и получить вычисленное значение для использования в различных компонентах, мы можем использовать Vuex Геттерс
Используя это в нашем шаблоне:
Как redux делает это
Redux имеет mapstatetoponops ()
Метод, который передается на компонент более высокого порядка соединить
предоставляется React-redux
библиотека. Эти состояния теперь доступны как реквизиты в нашем компоненте.
//component import { connect } from 'react-redux'; const mapStateToProps = (state) => { return { todos: state }; } export default connect(mapStateToProps)(App);
Redux не предоставляет никакой аналогичной функции для Геттерс
, мы можем написать наши собственные методы утилиты в отдельном файле и импортируйте их везде, где необходимо, используя это в шаблоне:
renderList() { return this.props.todos.map(item => { return (
Изменение состояния
Переменная состояния не должна быть изменена напрямую. Мы используем специальные методы для изменения/обновления их, чтобы его можно было отследить должным образом.
Как Vuex это делает
Единственный способ на самом деле изменить состояние в магазине Vuex – это совершив Мутация Отказ Мутации Vuex очень похожи на события; Каждая мутация имеет тип строки и обработчик. Функция обработчика – это то, где мы выполняем фактические модификации состояния, и она получит состояние в качестве первого аргумента.
//store.jsmutations: { addItem(state, payload) { state.todos.push({id:GLOBAL_ID++, title: payload, completed: false}); }, togglecompletion(state, id) { state.todos.forEach( item => { if(item.id === id) item.completed = !item.completed; }) }, removeItem(state, index) { state.todos.splice(index, 1); } }
Мутации также принимают полезную нагрузку как дополнительный второй аргумент, если мы должны пройти больше данных, то мы можем либо отправить массив или объекты в полезной нагрузке.
Как redux делает это
В Redux методы модификации состояния также написаны в редукторах.
//reducer/index.js const todos = (state = initialState, action) => { switch (action.type) { case "ADD_ITEM": return [ ...state, { id: GLOBAL_ID++, title: action.title, completed: false } ]; case "TOGGLE_COMPLETION": console.log('action', action); return state.map(todo => todo.id === action.id ? { ...todo, completed: !todo.completed } : todo ); case "REMOVE_ITEM": return state.filter(todo => todo.id !== action.id); default: return state; } };
Редукторы поддерживают как состояние, так и их методы модификации, эти методы называются Диспетчерские действия Отказ Эти действия также принимают полезную нагрузку для отправки данных из нашего приложения в наш магазин Redux. (Помните, в условиях redux неизменяются)
//actions/index.js let nextTodoId = 0; export const addItem = title => { return { type: "ADD_ITEM", id: nextTodoId++, title }; }; export const toggleCompletion = id => { return { type: "TOGGLE_COMPLETION", id }; }; export const removeItem = id => { return { type: "REMOVE_ITEM", id } };
Мы также создаем новый файл для хранения всех наших действий, это не принуждение, но это заставляет наш код выглядеть более организованным. Вместо того, чтобы делать это в более поздней части кода, давайте сделаем это сейчас.
Изменение состояния из наших компонентов
Как Vuex это делает
Vuex предоставляет помощник методом Mapmutations ()
Чтобы получить доступ к нашим мутациям в компонентах.
methods: { ...mapMutations([ 'addItem', 'togglecompletion', 'removeItem', ]) }
После отображения эти методы могут затем доступны как нормальные методы компонентов, используя эти мутации в нашем компоненте:
removeTodo: function(index) { this.removeItem(index); }
Как redux делает это
Похоже на mapstatetoponops ()
Redux предоставляет нам другой помощник по имени mapdispatchtopops ()
передал нашу HOC.
const mapDispatcherstoProps = dispatch => { return { toggleCompletion: (id) => dispatch(toggleCompletion(id)), removeItem: (id) => dispatch(removeItem(id)), addItem: (title)=> dispatch(addItem(title)), addItemFromWeb: ()=> dispatch(addItemFromWeb()) } } export default connect(mapStateToProps, mapDispatcherstoProps)(App);
Этот метод получает Отправка
В качестве аргумента этот метод отправки используется для совершения наших действий. Эти действия теперь сопоставлены на локальные методы, которые доступны через реквизиты, как таковые:
Теперь наш список для списка приложение полностью функционально, мы можем добавить элементы, проверять завершенные элементы и удалить элементы.
Создание асинхрониза
Расширяя нашу приложение для списка, давайте скажем, мы хотим загрузить список для пользователей, хранящегося на сервере, мы не можем позвонить на сервере непосредственно из наших мутаций Vuex или действия Redux, поскольку они являются синхронными методами. Нам нужны особые способы достижения этого.
Как Vuex это делает
Мутации являются чистыми синхронными функциями, мы не можем вызвать побочные эффекты в наших мутациях. Чтобы сделать async звонки, Vuex имеет Действия
Отказ Действия похожи на мутации, но вместо мутации государства, действия совершать
мутации.
//store.js actions: { addItemFromWeb(context) { axios.get('[https://jsonplaceholder.typicode.com/todos/1'](https://jsonplaceholder.typicode.com/todos/1%27)) .then((response) => { console.log(response); context.commit('addItem', response.data.title) }) .catch((error) => console.log(error)); } }
В приведенном выше примере мы используем Axios
Библиотека, чтобы сделать HTTP Call.
Чтобы использовать эти действия в наших компонентах, Vuex предоставляет нам Карты ()
Метод помощника.
methods: { ...mapActions([ 'addItemFromWeb' ]) }
Как redux делает это
Redux не предоставляет ни одного раствора коробки, так как Vuex, следовательно, нам нужен Средние годы сделать асинхронные звонки.
Для достижения этого мы используем промежуточное программное обеспечение под названием Redux-Thunk.
Это промежуточное программное обеспечение очень проста, она проверяет, является ли действие функцией. Если это так, то эта функция вызывается с отправлять.
Если нет, редукторы называются напрямую.
import { applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; const store = createStore( reducer, applyMiddleware(thunk), );
Сейчас в Actions.js
Мы создаем нашу функцию Async:
export const addItemFromWeb = () => { return dispatch => { axios.get('[https://jsonplaceholder.typicode.com/todos/1'](https://jsonplaceholder.typicode.com/todos/1%27)) .then((response) =>{ console.log(response); dispatch(addItem(response.data.title)); }) .catch((error) => { console.log(error); }) } }
Управление приложениями и масштабированием
По мере роста нашего заявления у нас будет больше государств для управления, мы не можем иметь единого store.js
Файл для vuex или один redeber.js
Файл для redux, нам нужно Vuex позволяет нам разделить наш магазин в модули
Отказ Каждый модуль может содержать собственное состояние, мутации, действия, счетчики и даже вложенные модули.
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> `moduleA`'s state store.state.b // -> `moduleB`'s state
Внутри мутаций модуля и GetTers первый полученный аргумент будет модулем местное государство Отказ
Каждый модуль
Может быть написан в отдельных файлах, которые можно импортировать в store.js.
Как redux делает это
Мы можем разделить наш корневой редуктор на несколько редукторов, а затем объединить их вместе. Каждый редуктор будет отвечать за управление государствами внутри них.
import { combineReducers } from 'redux' import todos from './todos' import counter from './counter' let reducers = combineReducers({ todo: todos, ctr: counter }) const store = createStore(reducer); ReactDOM.render(, document.getElementById('root'));
Библиотека Redux предоставляет нам функцию под названием Коммунатории
объединить все наши редукторы в один редуктор. (Обратите внимание, что мы не можем напрямую доступ к состояниям, присутствующим в одном редукторе в другом) Данные, необходимые для редуктора, должны быть переданы компонентом через действия.
Заключение
Мы сравниваем два очень популярных библиотека государственных управлений, как вдохновленные архитектурой Flux, оба имеют одинаковую целую целую цель, но и делает другой путь для его достижения.
Я надеюсь, что вы нашли это полезно. Если это так, обязательно нажмите на кнопку «Нравится»
Живая демонстрация
Vue + Vuex.
React + Redux.
Демо-код приложения
Vuex todo github
Redux todo github