【问题标题】:Should re-routing be wrapped into an action?重新路由是否应该包含在一个动作中?
【发布时间】:2016-08-05 03:10:51
【问题描述】:

我面临的一般问题与动作设计策略有关:何时以及如何调用动作以及何时不调用?

Mantra(其前端使用React,路由使用Meteor's FlowRouter)中,我有一个包含ListItem 的UI 组件。

如果我想重新路由到 onClick 中的项目自己的页面,最好的策略是什么?

我在想:

  1. 添加一个容器并将gotoPage 函数添加到调用FlowRouter.goprops
  2. 在 UI 的 onClick 事件中调用 gotoPage

这是否足够,或者我应该为此添加一个操作?我想为了让动作组成一个完整且可重播的所有已发生事件的日志,必须创建一个动作。为了回放用户所做的所有事情,这将是至关重要的。但与此同时,我在想:使用href 而不产生动作似乎也可以。 “可重播性”通常是不可取的,URL 更改是否会以某种方式隐式创建操作,或者还有其他一些我没有得到的东西?

抱歉,我是动作游戏的新手 :)

【问题讨论】:

    标签: javascript reactjs action url-routing mantrajs


    【解决方案1】:

    编辑:添加了将单个参数绑定到操作函数的简单示例。

    我认为这个问题有很多解决方案,但我会尝试描述我通常做的事情(编写的代码未经测试)。假设您有以下列表项组件components/list_item.js

    import React from 'react';
    
    class ListItem extends React.Component {
    
      render() {
        const { clickHandler, label } = this.props;
        return <li onClick={clickHandler}>{label}</li>;
      }
    
    }
    
    // add default props and propTypes here...
    
    export ListItem;
    

    还有一个列表包装组件components/list.js:

    import React from 'react';
    
    import ListItem from './list_item.js';
    
    class List extends React.Component {
    
      renderItem({ clickHandler, label, arg }) {
        return <ListItem clickHandler={arg ? this.props[clickHandler].bind(this, arg) : this.props[clickHandler]} label={label} />;
      }
    
      renderList() {
        const { items } = this.props;
    
        return items.map((item) => {
          return renderItem(item);
        });
      }
    
      render() {
        return <ul>{this.renderList()}</ul>;
      }
    
    }
    
    // add default props and propTypes here...
    
    export List;
    

    如果我想创建一个新列表,我只需创建一个新容器,如下所示containers/my_list.js:

    import List from '../components/list';
    import {useDeps, composeWithTracker, composeAll} from 'mantra-core';
    
    export const composer = ({}, onData) => {
    
      const items = [
        {
          clickHandler: 'goto',
          label: 'Goto document',
          arg: 'MyRoute'
        },
        {
          clickHandler: 'remove',
          label: 'Remove document'
        }
      ];
    
      onData(null, {items});
    };
    
    export const depsMapper = (context, actions) => ({
      goto: actions.myList.goto,
      remove: actions.myList.remove,
      context: () => context
    });
    
    export default composeAll(
      composeWithTracker(composer),
      useDeps(depsMapper)
    )(List);
    

    此容器链接到例如这些操作actions/my_list.js

    export default {
    
      goto({ FlowRouter }, route) {
        FlowRouter.go(route);
      },
    
      remove({ Collections }, _id) {
        Collections.Documents.remove({ _id })
      }
    
    }
    

    使用此模式创建列表的通用结构。如果您发现此模式有用,以及您对我当前的解决方案是否有任何改进,请告诉我。您也可以在设计容器时将参数绑定到单击处理程序(上例中未说明)。

    【讨论】:

    • 所以,答案是:1) 仍然应该为每次路由尝试创建一个操作? 2)事实上,应该为您想要访问的每个 URL 创建一个特定的操作,而不是为任何 URL 创建一个通用的路由操作?如果是这样: q1)您是否甚至允许使用&lt;a href=... 进行链接,看看这不会创建一个动作(有些路由触发一个动作而有些不触发似乎不一致)?和 q2) 为每个 url 使用单个操作而不是在 URL 之间共享一个操作有什么好处?
    • 无需为每个 URL 创建新操作,使用 depsMapper 您可以链接到您想要的任何操作。我通常将经常使用的操作放在一个名为shared.js(或类似名称)的自己的文件中,并在整个模块中使用它。所以goto: actions.myList.goto 可以是例如:goto: actions.shared.goto。我现在看到我的示例没有说明如何将参数绑定到操作函数,我将用一个简单的示例进行更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    相关资源
    最近更新 更多