将父母道具传给儿童反应

时间:2015-06-01 18:29:22

标签: javascript reactjs react-jsx

我有一个Legend,其中包含多个Legend.Items子项。我遇到了一个问题,目前onClick可以取消选择所有我想避免的后果项目。是否可以在onClick组件中设置某种状态为Legend的{​​{1}}处理程序,并检查是否有clicked个图例项“选中/淡化”, n - 1是图例项目的总数?我查看了JSX Spread属性,但因为我使用的是n,我不确定如何使用它们或者它们是否适用于此上下文。

我还看了一下这篇博客文章(http://jaketrent.com/post/send-props-to-children-react/),但对我来说看起来有些笨拙,我觉得可能有更传统的方式。我是ReactJS的新手,所以如果我需要提供更多上下文,请告诉我!

我的代码:

LEGEND.JSX

{this.props.children}

RESPONSE.JSX RENDER FUNCTION

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,
};

1 个答案:

答案 0 :(得分:1)

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

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的初始状态作为道具传递给Item元素。通过这种方式,选择/取消选择所有内容变得非常容易。