在不使用状态/属性的情况下与父组件通信

Communicate with parent component without using state/props

本文关键字:情况下 组件 通信 属性 状态      更新时间:2023-09-26

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

我不想将其保留在应用程序状态(Redux)中。我无法将逻辑向上移动到父组件。

我的组件是:

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

我需要 B 知道 C 是展开的,这样它在展开时就不可拖动了。

我不能将展开/折叠的逻辑放在 B 中,因为 C 应该始终是可折叠/可展开的,独立于可拖动。

有没有简单的方法可以完成此操作,而无需在应用状态下具有每个项目的展开/折叠状态?

我已经读过 https://facebook.github.io/react/docs/context.html 但似乎仍处于实验阶段......

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

下面是一个示例: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)你总是可以渲染B(A渲染B,每个都包装一个C),但只需在B不应该可拖动时禁用可拖动行为(将其isDraggable传递给B)。然后,C 的可折叠状态可以存储在 B 中,并将一个道具传递给 C,因为 B 将永远在那里。

2)您可以将所有状态移动到A(不确定这是否是"应用程序状态"的意思)

如果不了解更多上下文,就很难提出建议。但在这种情况下,几乎有一种更好的方法来分解你的组件/应用状态,这样它就不会感觉"错误"。

相关文章: