将 Parent Prop 传递给 Children reactjs

Pass Parent Prop to Children reactjs

我有一个图例,其中包含多个Legend.Itemschildren。我遇到了一个问题,目前 onClick 可以取消选择所有具有我想避免的后果的图例项。是否可以在 Legend 组件中设置某种 onClick 处理程序,它可以有一些状态 clicked 并检查是否有 n - 1 个图例项 "selected/faded", n 是传奇项目的总数?我查看了 JSX Spread Attributes,但因为我使用的是 {this.props.children},所以我不确定如何使用它们或者它们是否可以在这种情况下工作。

我也看了一下这篇博文 (http://jaketrent.com/post/send-props-to-children-react/),但我觉得它有点老套,我认为可能有更传统的方法。我是 ReactJS 的新手,所以如果我需要提供更多上下文,请告诉我!

我的代码:

LEGEND.JSX

var React = require('react');
var cn = require('classnames');

// Have legend hold state about how many clicked
var Legend = React.createClass({
  getInitialState: function () {
    return { clicked: 0 }
  },

  render: function () {
    console.log(this.props.children);

    return (
      <ul className="legend inline-list">
        {this.props.children}
      </ul>
    );
  },
});

Legend.Item = React.createClass({
  getInitialState: function () {
    return { hover: false, clicked: false };
  },

  handleMouseOver: function () {
    this.setState({ hover: true });
    this.props.mouseOver(this.props.name);
  },

  handleMouseOut: function () {
    this.setState({ hover: false });
    this.props.mouseOut(this.props.name);
  },

  handleClick: function() {
    if (this.state.clicked) {
      this.setState({ clicked: false });
      this.props.click(this.props.name);
    } else {
      this.setState({ clicked: true });
      this.props.click(this.props.name);
    };
  },

  render: function () {
    var swatchClasses = cn({ 'swatch': true, 'legend-item-fade': this.state.hover, 'c3-legend-item-hidden': this.state.clicked })
    var spanClasses = cn({ 'legend-item-fade': this.state.hover, 'c3-legend-item-hidden': this.state.clicked })

    return (
      <li className="legend-item">
        <i className={swatchClasses}
          onClick={this.handleClick}
          onMouseEnter={this.handleMouseOver}
          onMouseLeave={this.handleMouseOut}
          style={{ "backgroundColor": this.props.color }}></i>
        <span className={spanClasses}
          onClick={this.handleClick}
          onMouseEnter={this.handleMouseOver}
          onMouseLeave={this.handleMouseOut}>
          {this.props.name}
        </span>
      </li>
    );
  },
});

module.exports = {
  Legend: Legend,
};

RESPONSE.JSX 渲染函数

<Legend>
  {newColumns.map(function (column) {
    return (
      <Legend.Item name={column.name}
        color={column.color}
        click={this.onLegendClick}
        mouseOut={this.onLegendMouseOut}
        mouseOver={this.onLegendMouseOver}/>
    );
  }.bind(this))}
</Legend>

我认为最好和最简单的方法是使用回调。

Legend 中重新创建子项的组件,通过回调 Legend:

来扩充他们的道具
let legendItems = React.Children.map(this.props.children, child => 
    React.cloneElement(child, { updateLegendCounter: this.updateLegend})
);

Legend中的回调是这样的:

updateLegend() {
    this.setState({clicked: clicked + 1})
}

最后,在你的渲染方法中,你区分什么时候

if (this.state.clicked === children.length-1)

此外,我会将 clicked 的初始状态作为 prop 传递给 Item 元素。这样就变得很容易 select/deselect all.