【问题标题】:How to implement a React container which can handle all events from its sub-components?如何实现一个可以处理来自其子组件的所有事件的 React 容器?
【发布时间】:2018-02-28 21:56:51
【问题描述】:

假设容器包含 3 个按钮:

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

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

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

【问题讨论】:

    标签: reactjs components


    【解决方案1】:

    Name 是在按钮中使用的有效 html 属性。如果您想使用 React 来控制它,您可以简单地将 state 属性归因于所选按钮的名称。使用该状态,您可以控制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>
      );
    }
    

    【讨论】:

      【解决方案2】:

      可以考虑使用按钮作为子组件

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

      【讨论】:

        【解决方案3】:

        Working Demo

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

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

        检查演示的输出

        【讨论】:

          猜你喜欢
          • 2011-09-06
          • 1970-01-01
          • 2010-11-06
          • 2017-07-10
          • 1970-01-01
          • 2012-09-30
          • 1970-01-01
          • 1970-01-01
          • 2020-01-26
          相关资源
          最近更新 更多