javascript - 在单个页面上多次渲染 React/Redux 应用程序?

标签 javascript reactjs redux

我一直在开发用于构建报价的 React/Redux 应用程序。我的状态的粗略简化看起来像这样:

{
  account: { name: 'john doe' },
  lineItems:[
    { product: {id: 123, ...}, price: 10, units: 5 },
    { product: {id: 124, ...}, price: 10, units: 5 },
  ],
  modifiers: { couponCode: 'asdf', vip: true }  
}

我的 reducer 会被切成这样的:

const appReducer = combineReducers<GlobalState>({
  account: accountReducer,
  lineItems: lineItemReducer,
  modifiers: modifersReducer,
});

我最近收到一个要求,我基本上需要能够在单个页面上多次呈现整个应用程序(基本上在单个页面上显示不同帐户的 1 个或多个引号)。因此,单个状态现在需要看起来像这样:

{
  quotes: {
    "0": {
      account: { name: 'john doe' },
      lineItems:[
        { product: {id: 123, ...}, price: 10, units: 5 },
        { product: {id: 124, ...}, price: 10, units: 5 },
      ],
      modifiers: { couponCode: 'asdf', vip: true }  
    },
    "1": {
      account: { name: 'billy jean' },
      lineItems:[
        { product: {id: 123, ...}, price: 10, units: 5 },
      ],
      modifiers: { couponCode: '', vip: false }  
    },
  }
}

但显然,这种新的状态形状并不真正适用于我对 reducers 的切片方式。此外,似乎我必须重构我的所有操作,以便我知道他们应该对哪个报价进行操作?例如,如果我有这样的操作:

{
  type: 'UPDATE_PRICE'
  payload: { productId: 123, newPrice: 15 }
}

两个引号上的产品 123 似乎都会更新。

也许有一些方法可以在页面上呈现整个应用程序而不必重构我的整个状态?我不确定我最好的方法是什么不需要我重写应用程序的大部分内容。

最佳答案

这应该会给您灵感。它基本上是在另一个 reducer 中使用一个 reducer 。就像在另一个函数体内使用一个函数一样简单。您可以在 runkit.com 上运行它

const { createStore, combineReducers } from 'redux';

const UPDATE_ACCOUNT = 'app/updat-account';
const ADD_QUOTE = 'quote/add-quote';

const appActions = {
  updateAcount: (q_id, a) => ({ type: UPDATE_ACCOUNT, payload: { q_id, name: a }}),
};

const quoteActions = {
  addQuote: q_id => ({ type: ADD_QUOTE, payload: q_id }),
};


const accountReducer = (app = {}, action) => {
  const { type, payload } = action;
  switch (type) {
    case UPDATE_ACCOUNT:
      return { ...app, name: payload.name }
    default:
      return app;
  }  
};

const appReducer = combineReducers({
  account: accountReducer,
  lineItems: (app ={}, action) => app, // just a placeholder
  modifiers: (app ={}, action) => app, // just a placeholder
});

const quoteReducer = (state = {}, action) => {
  const { type, payload } = action;
  switch (type) {
    case ADD_QUOTE:
      return { ...state, [payload]: {} };
    case UPDATE_ACCOUNT: {
      const app = state[payload.q_id];
      return app
        ? { ...state, [payload.q_id]: appReducer(state[payload.q_id], action) }
        : state;
    }
    default:
      return state;
  }
}


const store = createStore(quoteReducer);

store.dispatch(quoteActions.addQuote(3));
store.dispatch(quoteActions.addQuote(2));

store.dispatch(appActions.updateAcount(3, 'apple'));
store.dispatch(appActions.updateAcount(4, 'orange')); // non-existent quote

store.getState():

/**
{
  "2": {},
  "3": {
    "account": {
      "name": "apple"
    },
    "lineItems": {},
    "modifiers": {}
  }
}
*/

关于javascript - 在单个页面上多次渲染 React/Redux 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48350767/

相关文章:

javascript - 定义 JavaScript 对象文字,以便数组中的所有对象都存在属性?

javascript - 使用 React Router 4 和哈希路由获取页面位置

javascript - 使用 Jest 测试 React/Redux 组件

javascript - Bootsnipp 步骤向导无法正确呈现

javascript - 如何使用 grunt-contrib-imagemin 的插件无损优化图像?

Javascript从其他函数访问局部变量

javascript - 使用 React Router 6 导航时恢复滚动位置

javascript - React 片段序列化。错误: Cannot convert a Symbol value to a string

javascript - React + Redux,render() 没有返回任何内容

javascript - 如何将此刷新操作称为连续后台作业