Как грамотно реализовать стейт в приложении React-Redux

124
04 ноября 2021, 23:30

Всем доброго времени суток. Делаю простое приложение на React-Redux, опыта с React немного. Столкнулся со странной структурой стейта приложения. Привожу исходный код. Actions:

export const actionView = (_view) => {
  return {
    type: 'VIEW', view: _view,
  }
};
export const actionDel = (_id) => {
  return {
    type: 'DEL', id: _id
  }
};
export const actionEdit = (_id, _spec) => {
  return {
    type: 'EDIT', id: _id, spec: _spec
  }
};
export const actionAdd = (_spec) => {
  return {
    type: 'ADD', spec: _spec
  }
};
export const actionType = (_scanCode) => {
  return { type: 'TYPE', scanCode: _scanCode }
};
export const actionSetSpec = _spec => {
  return { type: 'SET_SPEC', spec: _spec }
};
export function performView() {
  return (dispatch, getState) => {
    let Resp = service.view();
    dispatch(actionView(Resp));
  }
}
export function performDel(id) {
  return (dispatch, getState) => {
    service.del(id);
    dispatch(actionDel(id));
  }
}
export function performEdit(id, spec) {
  return (dispatch, getState) => {
    service.edit(id, spec);
    dispatch(actionEdit(id, spec));
  }
}
export function performAdd(spec) {
  return (dispatch, getState) => {
    service.add(spec);
    dispatch(actionAdd(spec));
  }
}

Исходник с редьюсерами:

import { combineReducers } from 'redux';
import Immutable from 'seamless-immutable';
const iniState = Immutable({ view: [], shift: false, lang: 'en', caps: false, spec: '', scanCode: 0 });
export function view(state = iniState, action = {}) {
  let newState;
  if (action.type === 'VIEW') {
    newState = state.merge({ view: action.view });
    return newState;
  } else {
    return iniState;
  }
};
export function del(state = iniState, action = {}) {
  let newState;
  if (action.type === 'DEL') {
    newState = state.merge({ id: action.id });
    return newState;
  } else {
    return iniState;
  }
}
export function add(state = iniState, action = {}) {
  let newState;
  if (action.type === 'ADD') {
    newState = state.merge({ spec: action.spec });
    return newState;
  } else {
    return iniState;
  }
}
export function edit(state = iniState, action = {}) {
  let newState;
  if (action.type === 'EDIT') {
    newState = state.merge({ id: action.id, spec: action.spec });
    return newState;
  } else {
    return iniState;
  }
}
export function setSpec(state = iniState, action = {}) {
  let newState;
  if (action.type === 'SET_SPEC') {
    newState = state.merge({ spec: action.spec });
    return newState;
  } else {
    return iniState;
  }
}
export function type(state = iniState, action = {}) {
  let newState;
  if (action.type === 'TYPE') {
    if (action.scanCode > 0) {
      newState = state.merge({ spec: state.spec + Symbol(action.scanCode).toString() });
    } else {
      newState = state.merge({ scanCode: action.scanCode });
    }
    return newState;
  } else {
    return iniState;
  }
}
export default combineReducers({ view, del, edit, add, type, setSpec });

Привожу метод Render одного из компонентов:

render() {
  let view = this.props.view;
  console.log(view);
...
 }
  const mapStateToProps = (state) => {
  return {
   view: state,
   scanCode: state.scanCode
   }
}

В консоли вижу:

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

Answer 1

Стейт так выглядит потому что так работает combine reducers - он разбивает стейт на несколько кусков, каждый из которых обрабатывается своим редьюсером. Вы, похоже, хотите выстроить редьюсеры в цепочку, чтобы action проходил через них по очереди, и чтобы на выходе получался стецт, пропущенный через все редьюсеры. Это делается через https://www.npmjs.com/package/reduce-reducers.

READ ALSO
JS: имя свойства объекта из переменной

JS: имя свойства объекта из переменной

Необходимо обратиться к вложенному свойству объекта js, имя которого задано переменнойОбщая картина такова:

205
Uncaught (in promise) DOMException

Uncaught (in promise) DOMException

Скрипт не воспроизводит аудиоПочему?

93
Не могу запустить скачанный код node.js

Не могу запустить скачанный код node.js

Загрузил код приложения с githab'а и не могу запустить у себя на компе

93
Как достать св-во из объекта

Как достать св-во из объекта

Есть объект ranges в качестве св-ва принимает объект {…}

80