与父组件通信而不使用state / props

时间:2016-01-22 00:12:39

标签: javascript reactjs

我需要一个父组件来知道它的子组件何时从折叠状态变为扩展状态,反之亦然。

我不想将其保持在应用状态(Redux)。我无法将逻辑移动到父组件。

我的组件是:

  • 我有组件C,它是可以展开/折叠的项目。
  • 然后我有组件B,它是特定情况下组件C的包装器(给它可拖动的行为)。
  • 最后是组件A,它在循环中列出组件C. A,有时将B包裹在B中,有时不包括(当物品不能拖动时)。

我需要B知道C是否已扩展,因此在扩展时它不会被拖动。

我无法将扩展/折叠逻辑放在B中,因为C应该始终是可折叠/可扩展的,而不管是否可拖动。

有没有简单的方法来实现这一点,而无需在应用程序状态中拥有每个项目的展开/折叠状态?

我已阅读https://facebook.github.io/react/docs/context.html,但似乎仍处于试验阶段......

2 个答案:

答案 0 :(得分:1)

您可以将扩展状态保留在C组件内,并使用通过C组件的props传递的回调更新B组件的可拖动状态。 通过这种方式,两个组件都保持自己的状态,无需在A组件或App状态(Redux one)中添加状态。

以下是https://jsfiddle.net/snahedis/69z2wepo/28567/

的示例
var sampleList = [{id: 1, draggable: true},{id: 2, draggable: false}];

var Acomponent = React.createClass({
  render: function() {
    return (
      <div>
        {sampleList.map(function(component) {
          if (component.draggable) {
            return <Bcomponent key={component.id} />;
          } else {
            return <Ccomponent key={component.id} />;
          }
        })}
      </div>
    );
  }
});

var Bcomponent = React.createClass({
  getInitialState: function() {
    return {
        draggable: true
    }
  },
  hasBeenToggled: function() {
    this.setState({
        draggable: !this.state.draggable
    });
  },
  render: function() {
    return <Ccomponent draggable={this.state.draggable} toggleExpandableCallback={this.hasBeenToggled} />;
  }
});

var Ccomponent = React.createClass({
  getInitialState: function() {
    return {
        expanded: false
    }
  },
  toggleExpandable: function() {
    this.setState({
        expanded: !this.state.expanded
    });

    if (typeof this.props.toggleExpandableCallback === "function") {
        this.props.toggleExpandableCallback();
    }
  },
  render: function() {
    return (
      <div>
        <div>I'm the C component and my expanded state is : {this.state.expanded.toString()}</div>
        <div>{(this.props.draggable) ? "oh, and I'm draggable !" : "and I'm saddly not draggable"}</div>
        <button onClick={this.toggleExpandable}>Change expandable state</button>
      </div>
    );
  }
});

ReactDOM.render(
  <Acomponent />,
  document.getElementById('container')
);

答案 1 :(得分:0)

一些想法:

1)你总是可以渲染B(A渲染B,每个渲染一个C),但只是在B不可拖动时禁用B中的可拖动行为(将其传递给像isDraggable这样的东西B)。然后,C的可折叠状态可以存储在B中,并将支柱传递给C,因为B将始终存在。

2)你可以将所有状态移动到A(不确定这是“app state”的意思)

如果不了解更多背景,很难建议。但在这种情况下,几乎有一种更好的方法可以打破你的组件/应用程序状态,这样就不会觉得“错误”。