首页 文章

ReactJS . 如何获得反应组件内的元素状态

提问于
浏览
1

请帮助我获取反应组件中的元素状态或其他一些自定义功能以及我需要的信息 . 每个td标签都包含反应组件Block1 . 简化的代码结构如下

class Block2 extends React.Component {
render() {
  return (
    <table>
      <tbody>
        <tr>
          <td>
            <Block1 />
          </td>
          <td>
            <Block1 />
          </td>
        </tr>
      </tbody>
    </table>
  )}}

Block1 - 反应包含div元素的组件 . Block2位于组件Block3内 . 如何通过单击某个按钮从Block3获取Block1的状态?现在,我可以获得Block1的列表,可能会看到道具,但我看不到状态 . 或者我可以获取DOM td元素并查看子类classNames(我在各州寻找)但我看不到道具......

1 回答

  • 1

    除非您使用像Redux这样的库,否则您必须执行以下操作来解决您的问题:
    将状态存储在 Block3 而不是 Block1 中 . 然后将任何将此状态更改为 Block3 的函数从 Block3 传递到 Block2Block1 . 如果在 Block1 中发生任何更改,请调用此函数 . 模式应该是:

    class Block3 {
      changeState(value) {
        this.setState({ stateValue: value });
      }
      render() {
        return (
          <Block2 changeState={this.changeState}/>
        )
      }
    }
    
    class Block2 extends React.Component {
    render() {
      return (
        <table>
          <tbody>
            <tr>
              <td>
                <Block1 changeState={this.props.changeState} />
              </td>
              <td>
                <Block1 changeState={this.props.changeState} />
              </td>
            </tr>
          </tbody>
        </table>
      )}}
    
    
    class Block1 {
      changeHandler(ev) {
        this.props.changeState(ev.target.value);
      }
      render() {
        return (
          <button onClick={this.changeHandler}/>
        )
      }
    }
    

    如果您确实想要访问父组件中的子 state ,请考虑使用 refs

    class Block2 {
      render() {
        return <Block1 ref={ (childComponent) => { this.block1Child = childComponent; } } />;
        // Now you may use this.block1Child to access child component's state eg: this.block1Child.setState({})
      }
    }
    

    编辑:看到你的代码后我的解决方案:

    import React, { Component } from 'react';
    import './Hall.css';
    
    class HallCol extends Component {
        constructor(props) {
          super(props);
          this.state = {
            chair_cls:'chair-default'
          };
          this.handleClick = this.handleClick.bind(this);
        }
    
        handleClick(e) {
          let chair_cls = null;
          if(this.state.chair_cls==="chair-default") {
            chair_cls = 'chair-sold';
            this.props.updateCount(1, this.props.seat_number);
          } else {
            chair_cls = 'chair-default';
            this.props.updateCount(-1, this.props.seat_number);
          }
    
          this.setState({
            chair_cls: chair_cls
          });
        }
    
        render(){
          return(
                <div className={this.state.chair_cls} onClick={this.handleClick}>
                  <div className="backrest">
                      <p>{this.props.seat_number}</p>
                  </div>
                  <div className="armrest-left">
                  </div>
                  <div className="armrest-right">
                  </div>
                </div>
            );
        }
    }
    
    class Table extends React.Component {
      constructor() {
        super();
        this.genRow = this.genRow.bind(this);         // this is method binding
      }
    
      genRow() {
        var rows = this.props.rows;
        return rows.map(function(v, i) {
          var tmp = v.map(function(v2, j) {
            return (
              <td key={'td' + i + '_' + j} className='chair-cell' >
                {v2}
              </td>
            );
          });
    
          return (
            <tr key={'tr' + i}>
              {tmp}
            </tr>
          )
        });
      }
    
      render() {
        return (
          <table className="hall-grid" >
            <tbody>
              {this.genRow()}
            </tbody>
          </table>
        );
      }
    }
    
    class Hall extends React.Component {
      constructor(props) {
        super(props);
        var rows_num = this.props.rows;
        var cols_num = this.props.cols;
    
        this.AddRow = this.AddRow.bind(this);
        this.updateSeats = this.updateSeats.bind(this);
    
        var row = [];
        for (var i = 0; i < rows_num; i++) {
          var col = [];
          for (var k = 0; k< cols_num; k++) {
              col.push(<HallCol row = {i+1} seat_number = {k+1} updateCount={this.updateSeats} />);  // bind the passed function to parent
          }
          row.push(col);
        }
        this.state = {
          rows: row,
          bookedSeats: [],
          count: 0
        };
      }
    
      AddRow() {
        let newRows = this.state.rows;
        newRows.push([0, 0]);
        this.setState({rows: newRows});
      }
      updateSeats(val, seat_number) {
        let bookedSeatsUpdated;
        if( val === 1 ) {
          bookedSeatsUpdated = this.state.bookedSeats.concat(seat_number);
        } else {
          bookedSeatsUpdated = this.state.bookedSeats;
          let index = bookedSeatsUpdated.indexOf(seat_number);
          bookedSeatsUpdated.splice(index,1);
        }
        this.setState({
          bookedSeats: bookedSeatsUpdated,
          count: this.state.count + val
        });
      }
    
      render() {
        return (
          <div className="hall">
            <Table rows={this.state.rows} />
            <button className = "btn-default" onClick={() => {
                alert(this.state.count + 'seats : ' + this.state.bookedSeats);
              } }>
                TOTAL SOLD
            </button>
          </div>
        );
      }
    }
    
    export default Hall;
    

相关问题