简体   繁体   English

如何在 ReactJS 中的相邻元素之间进行通信?

[英]How can I communicate between adjacent elements in ReactJS?

I'm trying to construct a table in ReactJS that generates two rows for each element in an array.我正在尝试在 ReactJS 中构建一个表,为数组中的每个元素生成两行。 The problem I'm having trouble solving is generating them in such a way where row(n) can send a message to row(n+1).我无法解决的问题是以行(n)可以向行(n + 1)发送消息的方式生成它们。

The application of this is opening a detail view if one of the rows is clicked.如果单击其中一行,则此应用程序将打开详细视图。

Right now my approach is to generate the rows and pass row(n+1) as a prop of row.现在我的方法是生成行并将行(n+1)作为行的道具传递。

const orders = [
  // this is just some example data
  {
   "name": "lorem",
   "number": "20.00",
   "price": "20.00",
   "image": "http://localhost/path/to/image1.jpg"
  },
  {
   "name": "lorem",
   "number": "20.00",
   "price": "20.00",
   "image": "http://localhost/path/to/image1.jpg"
  },
];

const Orders = React.createClass({

  renderAllRows(order) {
    // this function would generate all the rows of the table
    const rows = [];
    orders.map(function (order, index) {
      const OrderDetailInstance = <OrderDetail display={false}  item={order} />
      // OrderDetailInstance is passed as a prop of OrderItemInstance
      const OrderItemInstance = <OrderItem detail={OrderDetailInstance} item={order}/>;
      rows.push(OrderItemInstance, OrderDetailInstance);
    });
    return rows;
  },

  render() {
    const { state } = this;
    const { orders } = state;
    const { isLastPage } = state;

    return (
        <Table>
          <tbody>
            {this.renderAllRows(orders).map(function(row) {
               return row;
            })}
          </tbody>
        </Table>
    );
  },
});

However this doesn't work, because while the prop is successfully passes, I do not know how to access methods on a react element.但是这不起作用,因为当 prop 成功通过时,我不知道如何访问 react 元素上的方法。 So I'm obviously going about this wrong.所以我显然是在做这个错误的。

Currently this is my unsuccessful approach to calling a method on a react element.目前,这是我在 react 元素上调用方法的失败方法。

const OrderItem = React.createClass({
  render() {
    const item = this.props.item;


    return (
      <tr>
        <td>{item.number}</td>
        <td>{item.number}</td>
        <td>
          <a onClick={this.openOrderDetail}>open detail</a>
        </td>
      </tr>
    );
  },

  openOrderDetail() {
    // This is where I'm trying to call the prop's method.
    this.props.detail.open();
  }
});

const OrderDetail = React.createClass({
  render() {
    const display = this.props.display;
    const classes = display ? classNames('') : classNames('hidden');
    return (
      <tr className={classes}>
        <td colSpan="3">
          <div>
            This is the detail of the previous row
          </div>
        </td>
      </tr>
    );
  },

  open() {
    // This should IDEALLY be exposed to any react element that has
    // OrderDetail as a prop.
    console.log("open");
  }
});

I'm open to the idea of using the state of the Orders class but I can't help feel that would be overkill.我对使用Orders类的状态持开放Orders但我不禁觉得这太过分了。

What if you just used CSS to show/not show the detail row unless it was preceded by a row with a certain class.如果您只是使用 CSS 来显示/不显示详细信息行,除非它前面是具有特定类的行,该怎么办。

So, your DOM could look like所以,你的 DOM 可能看起来像

<table>
  <!-- Item -->
  <tr class='show-detail'></tr>
  <!-- Detail -->
  <tr class='detail-row'></tr>
</table>

And your CSS could be something like你的 CSS 可能类似于

.detail-row { display: none}
.show-detail + .detail-row { display: block }

So a detail-row is not shown, unless it immediately follows a show-detail item.因此不会显示详细信息行,除非它紧跟在显示详细信息项之后。

Then, your OrderItem component is only worried about toggling a class on itself, rather than talking to it's sibling.然后,您的 OrderItem 组件只担心在自身上切换一个类,而不是与它的兄弟组件交谈。

Wrap OrderItem and OrderDetail in a container component, say: OrderView .OrderItemOrderDetail包装在一个容器组件中,例如: OrderView Keep the state of whether to show the detail or not in the new OrderView .在新的OrderView保持是否显示详细信息的state In your OrderView.render() , choose to show the detail row or not based on the state.在您的OrderView.render() ,根据状态选择是否显示详细信息行。 Instead of trying to call open() , just set the OrderView.state as required.不要尝试调用open() ,只需根据需要设置OrderView.state

This tutorial really helped me a lot.这个教程真的帮了我很多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM