Реализация архитектуры потока (ваниль с JS)


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

const application = () => {
  /* Init the model */
  let model = {
    page: null
  };
  
  /* redirects the reference from the old state to the new */
  const updateState = newState => model = newState;
  
  /* a reducer method, more are easily added */
  const UPDATE_PAGE = (model, newPage) => {
    let newState = Object.assign({}, model);
    newState.page = newPage;
    updateState(newState);
  };
  
  /* 
   * dispatch is a core function, directing every action
   * to the proper reducer depending on the `type`
   */
  const dispatch = action => {
    action.type === 'UPDATE_PAGE' ? 
      UPDATE_PAGE(model, action.page)
      : null;
  };
  
  /* An action mutating state */
  let updatePageAction = {
    type: 'UPDATE_PAGE',
    page: 1
  };
  
  console.log('initial model: ', model);
  
  /* simply dispatch the action */
  dispatch(updatePageAction);
  
  /* and the state is updated! */
  console.log('updated model: ', model);
};

application();



302
4
задан 11 апреля 2018 в 02:04 Источник Поделиться
Комментарии
2 ответа

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

/* 
* dispatch is a core function, directing every action
* to the proper reducer depending on the `type`
*/
const dispatch = action => {
action.type === 'UPDATE_PAGE' ?
UPDATE_PAGE(model, action.page)
: null;
};

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

/* a reducer method, more are easily added */
const UPDATE_PAGE = (model, newPage) => {
let newState = Object.assign({}, model);
newState.page = newPage;
updateState(newState);
};

Редуктор-это чистая функция, которая принимает 2 аргументов, современное состояние и отправляется действий и возвращает новое государство, основанное на государственной и проходило мероприятие. Вы можете думать об этом как "уравнения" часть приложения (да, как математические уравнения). Редукторы выглядеть так:

const initialState = { count: 0 }

const reducer = (state = initialState, action) => {
switch(action.type){
case 'INCREMENT':
return {...state, count: state.count + 1 }
case 'DECREMENT'
return {...state, count: state.count - 1 }
default:
return state
}
}

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


  • Редуктор чистый. Его результат это не повлияло на что-нибудь другое, чем его входы, что делает его глупым легко проверить.

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

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

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

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

// my-redux.js - The only part that is "Redux"
export const createStore = reducer => {
const subscribers = []
let currentState = null

return {
getState(){
return currentState
},
subscribe(fn){
subscribers.push(fn)
fn(currentState)
},
dispatch(action){
currentState = reducer(currentState, action)
subscribers.forEach(fn => fn.currentState)
}
}
}

// reducer.js - Where your app's logic goes.
const initialState = { count: 0 }

export const reducer = (state = initialState, action) => {
switch(action.type){
case 'INCREMENT':
return {...state, count: state.count + 1 }
case 'DECREMENT'
return {...state, count: state.count - 1 }
default:
return state
}
}

// app.js - How the app is brought together
import {createStore} from './my-redux'
import {reducer} from './reducer'
import {YourComponent} from './your-component'

const store = createStore(reducer)

YourComponent({
mount: 'somewhere',
onmount(){
store.subscribe(state => {
this.setYourState(state)
})
},
render(state) {
return (<button onclick="store.dispatch({ type: 'STH', data: 'NOT VALID JSX BUT WHATEVER' })">Click Me</button>)
}
})

Вы можете прочитать больше о трех принципах "возвращение" и как это просто направляя понятие, а не реальное осуществление.

3
ответ дан 11 апреля 2018 в 03:04 Источник Поделиться

Object.assign({}, model) не deepcopy, это shalow копию всего, вы должны рассмотреть возможность использования Immutablejs на Facebook или написать свою собственную библиотеку.

action.type === 'UPDATE_PAGE' ? 
UPDATE_PAGE(model, action.page)
: null;

Можно написать:

action.type === 'UPDATE_PAGE' && 
UPDATE_PAGE(model, action.page)

1
ответ дан 11 апреля 2018 в 03:04 Источник Поделиться