ReactJS + React Router:如何引用特定对象作为属性传递?

Jo *_* Ko 5 javascript reactjs react-jsx react-router

我目前有一张桌子,每个牢房都有一个按钮.单击按钮后,根据特定日期(星期一或星期二),类(1级或2级)和名称(Kev或Josh),如何将与表中特定按钮相关的对象推送到新的页?使用ReactJS + React路由器,对此有什么正确的解决方法?

当导航到新页面时,新页面将填充一个表,其中包含来自传入的对象的类信息,与单击的按钮单元格相关.

码:

http://jsfiddle.net/k7wbzc4j/16/

表行数据是否应该像这样构造并基于ID引用对象,如下所示,或者什么是更好的结构 - 想要根据单元格位置(日期,名称和类)找到该特定的id对象数量考虑在内)?

list: [
  {
    name: Kev
      monday: {
        class1: {
          id: 0,
          classTitle: abc,
          number: class1,
          info: {
            time: 1,
            classSize: 2,
          }
        },
        class 2: {
          id: 1,
          classTitle: def,
          number: class2,
          info: {
            time: 1,
            classSize: 2,
          }
        }
      },
      tuesday: {
        class1: {
          id: 2,
          classTitle: ghi,
          number: class1,
          info: {
            time: 1,
            classSize: 2,
          }
        },
        class 2: {
          id: 3,
          classTitle: jkl,
          number: class2,
          info: {
            time: 1,
            classSize: 2,
          }
        }
      },
  },

  {
    name: Josh, 
      monday: {
        class1: {
          id: 4,
          classTitle: mno,
          number: class1,
          info: {
            time: 1,
            classSize: 2,
          }
        },
        class2: {
          id: 5,
          classTitle: pqr,
          number: class2,
          info: {
            time: 1,
            classSize: 2,
          }
        }
      },
      tuesday: {
        class1: {
          id: 6,
          classTitle: stu,
          number: class1,
          info: {
            time: 1,
            classSize: 2,
          }
        },
        class2: {
          id: 7,
          classTitle: vwx,
          number: class2,
          info: {
            time: 1,
            classSize: 2,
          }
        }
      },
    }
  }
]
Run Code Online (Sandbox Code Playgroud)

例如,如果Kev在Monday列中的行class1想要将以下的道具传递给下一页:

class1: {
  id: 0,
  classTitle: abc,
  number: class1,
  info: {
    time: 1,
    classSize: 2,
  }
}
Run Code Online (Sandbox Code Playgroud)

将接受并赞成回答.先感谢您

tay*_*c93 4

这就是像redux这样的集中式状态管理工具派上用场的地方。您可以调度一个操作(类似SELECT_CLASS)来设置商店中选定的类,然后从新组件中读取该值。我推荐这种方法。

然而,还有另一种方法。每个浏览器历史记录条目都有一个 的概念state。因此,当您导航到新路线时,您可以将所选数据保存在该历史条目的状态中,然后在组件呈现时读取它。它看起来像这样:

保存状态:

router.push({
  to: '/path',
  state: class1
});
Run Code Online (Sandbox Code Playgroud)

阅读它:

router.location.state
Run Code Online (Sandbox Code Playgroud)

React 路由器文档:https://github.com/ReactTraining/react-router/blob/master/docs/API.md#pushpathorloc

更新:为 Redux 加油!首先,让我们为此定义动作+动作创建者:

export const SELECT_CLASS = 'SELECT_CLASS';
export const selectClass = (class) => {
  return {
    type: SELECT_CLASS,
    class,
  }
};
Run Code Online (Sandbox Code Playgroud)

现在,让我们看看处理这个问题的减速器是什么样子的:

import { SELECT_CLASS } from '/path/to/action'

const selectedClass = (
  state={},
  action
) => {
  switch (action.type) {
    case SELECT_CLASS:
      return action.class;
    default:
      returns state;
  }
};
Run Code Online (Sandbox Code Playgroud)

现在,假设您已经通过react-redux 连接了组件,如下所示:

// First argument is mapStateToProps, the second is mapDispatchToProps
// https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options
export default connect((state) => state, { selectClass } )(YourComponent);
Run Code Online (Sandbox Code Playgroud)

这是设置所选类别的方法:

  // Wherever you need to navigate
  function eventHandler(e) {
    const { selectClass } = this.props;
    selectClass(class1);
    router.push('/next/location');
  }
Run Code Online (Sandbox Code Playgroud)

在您的下一个组件中(也应该连接,但不需要mapDispatchToProps

render() {
  const { selectedClass } = this.props;
  // do what you need with the class.
}
Run Code Online (Sandbox Code Playgroud)

如果您需要任何设置 React + Redux 的帮助,这里的文档非常棒。如果我使用的 ES6 语法看起来不熟悉,这里的babel 文档是一个很好的参考

更新2:我拿了你的小提琴并用它运行:http://jsfiddle.net/k7wbzc4j/17/。每个按钮都有一个单击事件,该事件将获取正确的对象。

最终更新:以下是概要handleClick

handleClick(e) {
    const classTitle = e.target.innerHTML;
    let obj = undefined;
    data.forEach((schedule) => {
      ['monday', 'tuesday'].forEach((day) => {
        const classes = schedule[day];
        return Object.keys(classes).forEach((c) => {
            const cls = classes[c];
            if (cls.classTitle === classTitle) {
            obj = cls;
          }
        });
      })
    });

    if (obj) {
      // do your navigation here
    }
  }
Run Code Online (Sandbox Code Playgroud)

首先,我们用来迭代保存所有时间表的forEach数组。data然后,我们迭代每一天(当前仅mondaytuesday)以获取当前时间表当天的所有课程。然后,由于我们不知道所有类的名称,因此我们只需获取所有键(即类名称)并迭代它们。最后,我们可以获得实际的类对象并检查是否与classTitle单击的对象匹配。如果是这样,我们将该对象保存到obj. 最后,我们确保找到一个匹配的对象,然后采取一切必要措施来正确处理该点击。这非常混乱,但考虑到您的数据结构是必要的。我建议尝试更相关地存储这些数据,并分别存储每种类型的项目(例如UsersClassesDays、 和Schedules对象都在单独的数组中,并用 id 将它们链接在一起)

为了解决您对某些classTitles 相同的担忧,您还必须弄清楚谁的日程安排被点击(以及可能被点击的日期)。您可以通过多种方式执行此操作:data-user向每个按钮添加一个属性并在单击时获取该属性,实现“选定用户”的概念,创建一个新组件(可能称为UserSchedule),该组件在该表中呈现一行并采用, props,该用户的类。这样,您就会知道任何匹配的类都属于该用户。就像我说的:有很多方法。

至于向您展示如何将其传递给新组件,我已经演示了上面的两种方法:通过历史状态或将值存储在 redux reducer 中并将其作为 props 接收。做更多的事情就等于我为你解决了整个问题,但我不会这样做,因为这些东西坚持下去的唯一方法就是你自己做。相信自己,遵循我给出的建议,并使用互联网来解决您遇到的任何特定错误,您将会脱颖而出!