如何实现一个 React 容器,它可以处理来自其子组件的所有事件



>假设容器包含 3 个按钮:

<Container>
  <Button1/> <Button2> <Button3/>
</Container>

默认情况下,所有按钮都处于"正常"状态。如果我点击Button1,我希望Button1变成"活动"状态(有纯色背景(,Button2和Button3变成"非活动"状态(灰色边框(。

在 React 中实现这一目标的最佳方法是什么?

名称是在按钮中使用的有效 html 属性。如果你想使用 React 来控制这一点,你可以简单地将一个状态属性归因于所选按钮的名称。使用该状态,您可以控制 disabled 属性以及类名。

this.state = {
  activeButton: null
};
onButtonClick = (e) => {
  const { name } = e.target;
  this.setState({
    activeButton: name
  });
};
render() {
  const { activeButton } = this.state;
  return (
    <Component>
      <button 
        className={`${activeButton === 'one' && 'active' || ''}`} 
        onClick={this.onButtonclick}
        name="one"
        disabled={activeButton !== 'one'}>
          Button 1
      </button>
      <button
         className={`${activeButton === 'two' && 'active' || ''}`} 
         onClick={this.onButtonclick}
         name="two"
         disabled={activeButton !== 'two'}>
          Button 2
      </button>
      <button
        className={`${activeButton === 'three' && 'active' || ''}`}  
        onClick={this.onButtonclick}
        name="three"
        disabled={activeButton !== 'one'}>
          Button 2
       </button>
    </Component>
  );
}

您可以考虑将按钮用作子组件

class Button extends React.Component {
  constructor(props) {
    super(props);
    this.setActive = this.setActive.bind(this);
  }
  setActive() {
    this.props.onClick(this.props.value);
  }
  render() {
    return (<button onClick={this.setActive} className={this.props.active ? 'active' : ''}>
      {this.props.children}
      </button>);
  }
}
class Container extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      active: 0,
    };
    this.buttons = Array.from({ length: 5 }).map((v, index) => index);
    this.setActive = this.setActive.bind(this);
  }
  setActive(active) {
    this.setState({ active })
  }
  render() {
    return (<div>
      {
        this.buttons.map((value) => (<Button key={value} value={value} active={this.state.active === value} onClick={this.setActive}>Button #{value}</Button>))
      }
    </div>);
  }
}

工作演示

使您的组件如下所示,这肯定会起作用:

class App extends React.Component {
  constructor(props) {
    super(props)
    this.setActiveBackground = this.setActiveBackground.bind(this);
    this.state = {
      selectedCircle: {
     },
    };
  }
  setActiveBackground(name, event) {
     let selected = this.state.selectedCircle;
     selected = {};
     selected[name] = this.state.selectedCircle[name] == "selected" ? "" : "selected";
     this.setState({selectedCircle: selected});
  }

render() {
return (
    <div className="container">
        <div className="row">
                <div className="card-panel white">
                  <div className="center">
                    <p>Set Active background in selected button</p>
                    <button onClick={this.setActiveBackground.bind(this, "first")} className={this.state.selectedCircle["first"]}>Button 1</button>
                    <button onClick={this.setActiveBackground.bind(this, "second")} className={this.state.selectedCircle["second"]}>Button 2</button>
                    <button onClick={this.setActiveBackground.bind(this, "third")} className={this.state.selectedCircle["third"]}>Button 3</button>
                  </div>
                </div>
        </div>
    </div>
);
  }
}

检查演示以获取输出

最新更新