点击按钮

时间:2016-03-23 16:14:04

标签: javascript html reactjs

以下是HTML。

<script src="https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xtp1/t39.3284-6/12624079_897774290317920_1379776191_n.js"></script>
<script src="https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xfp1/t39.3284-6/12624052_751451571621845_431133942_n.js"></script>


<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>

<div class="row" id="container">
  <div class="controls">
    <span class="" id="controls-size">Size : 
        <button id="controls-size-small">SMALL</button>
        <button id="controls-size-med">MEDIUM</button>
        <button id="controls-size-large">LARGE</button>
    </span>

  </div>
  <div id="game-container">
  </div>
</div>

以下是Javscript

var SizeEnum = {
  SMALL: 1,
  MEDIUM: 2,
  LARGE: 3
};

var Board = React.createClass({
      getInitialState: function() {
        return {
          size: SizeEnum.MEDIUM
        };
      },

      componentWillMount: function() {
        if (this.state.size == SizeEnum.SMALL) {
          this.style = {
            width: 600 + 'px',
            height: 320 + 'px',
            margin: 'auto',
            border: '2px solid red'
          }
        } else if (this.state.size == SizeEnum.MEDIUM) {
          this.style = {
            width: 700 + 'px',
            height: 500 + 'px',
            margin: 'auto',
            border: '2px solid red'
          }
        } else if (this.state.size == SizeEnum.LARGE) {
          this.style = {
            width: 900 + 'px',
            height: 720 + 'px',
            margin: 'auto',
            border: '2px solid red'
          }
        }
      },

      render: function() {
          return ( < div style = {
            this.style
          } > < /div>
    )
  }

});

ReactDOM.render(<Board / > , document.getElementById("game-container"));

还有一些CSS

#game-container {
    position: relative;
    margin-top: 32px;
    border: 1px solid black;
    width: 100%;
}

我想要的是,当点击相应的按钮时,会将Board组件的大小调整为适当的大小。

我试过这样做

var board = ReactDOM.render(<Board />, document.getElementById("game-container"));

document.getElementById("controls-size-small").onclick = changeBoardSize;
document.getElementById("controls-size-med").onclick = changeBoardSize;
document.getElementById("controls-size-large").onclick = changeBoardSize;

function changeBoardSize(event) {
    var etid = event.target.id;
    console.log(etid);
    if (etid == "controls-size-small") {
        // method 1
        board.state.size = SizeEnum.SMALL;
    } else if (etid == "controls-size-med") {
        // method 2
        board.state.size = SizeEnum.MEDIUM;
        ReactDOM.render(<Board />, document.getElementById("game-container"));
    } else if (etid == "controls-size-small") {
        // method 3
        board.setState({size: SizeEnum.SMALL});
        ReactDOM.render(<Board />, document.getElementById("game-container"));
    }
}

但它没有用。

4 个答案:

答案 0 :(得分:3)

您无法像这样设置React组件的状态。组件应负责设置自己的状态。

在Board组件中,在componentDidMount中设置事件侦听器。最好的解决方案是让按钮成为React应用程序的一部分,但这超出了这个问题的范围。所以我们假设按钮不是React应用程序的一部分,然后执行以下操作:

var Board = React.createClass({
  ...
  ...
  componentDidMount: function(){
    var that = this;
    document.getElementById("controls-size-small").addEventListener('click', that.changeBoardSize, false);
    document.getElementById("controls-size-med").addEventListener('click', that.changeBoardSize, false);
    document.getElementById("controls-size-large").addEventListener('click', that.changeBoardSize, false);
  }

  changeBoardSize: function(e){
    /* get the element id and do the enum things here */
    this.setState({
      size: newSize
    });
  }
  render: function(){
    ...
    ...
  }
});

然后将所有componentWillMount样式内容移动到render函数。

更新

小提琴:https://jsfiddle.net/dannyjolie/r525ux66/

答案 1 :(得分:2)

你采取了错误的做法。关于反应的最难的部分是“反思中的思考”。如果你想让事情正常工作,那么直接进入DOM的概念,就像你正在使用document.getElementById一样,已不在桌面上。

最简单的方法是在Board组件的渲染功能中渲染按钮。然后,您可以在Board组件中放置一个单击处理程序来设置状态。

这应该让你开始:

    handleClick: function (event) {
       this.setState({ size: SizeEnum.SMALL });
    },
    render: function() {
              return ( 
                  <div>
                      <div style = { this.style}></div>
                      <input type="button" onClick={this.handleClick}
                  </div>
              )
    }

一旦你开始工作,如果你想将按钮与按钮分开,那么你将需要考虑使用Flux实现来将状态从一个组件传递给组件。

答案 2 :(得分:1)

您不应直接更改React组件的状态。请改用setState功能。当你致电setState时,React将重新渲染组件。

将新功能setSize添加到您的Board组件:

    var Board = React.createClass({
        getInitialState: function() {
          return {
            size: SizeEnum.MEDIUM
         };
     },
     setSize: function(size) {
        this._setStyle(size);
        this.setState({size: size});
     },
     _setStyle: fiunction(size) {
        if (size == SizeEnum.SMALL) {
             this.style = {
               width: 600 + 'px',
               height: 320 + 'px',
               margin: 'auto',
               border: '2px solid red'
            }
        } else if (size == SizeEnum.MEDIUM) {
            this.style = {
              width: 700 + 'px',
              height: 500 + 'px',
              margin: 'auto',
              border: '2px solid red'
           }
        } else if (this.state.size == SizeEnum.LARGE) {
            this.style = {
              width: 900 + 'px',
              height: 720 + 'px',
              margin: 'auto',
              border: '2px solid red'
           }
       }
     },
     componentWillMount: function() {
        this._setStyle(this.state.size);
     },
     // ................
     render: function() {
      return ( <div style={this.style}></div>)
     }
     });

     function changeBoardSize(event) {
         var etid = event.target.id;
         console.log(etid);
        if (etid == "controls-size-small") {
            board.setSize(SizeEnum.SMALL);
        } else if (etid == "controls-size-med") {
             board.setSize(SizeEnum.MEDIUM);
        } else if (etid == "controls-size-small") {
             board.setSize(SizeEnum.LARGE);
        }
      }

答案 3 :(得分:0)

这是一种反模式,尽管这是实现所需目标的正确方法。

由于ReactDOM.render返回呈现的组件的实例,您可以使用它并更新它的状态。

    function changeBoardSize(event) {
        var etid = event.target.id;
        console.log(etid);
        if (etid == "controls-size-small") {      
            board.setState({size: SizeEnum.SMALL});
        } else if (etid == "controls-size-med") {
            board.setState({size: SizeEnum.MEDIUM});     
        } else if (etid == "controls-size-small") {
            board.setState({size: SizeEnum.LARGE});
        }
    }

正确的方法是制作Board的按钮组件并在其上附加事件处理程序,例如:

var Board = React.createClass({
      getInitialState: function() {
        return {
          size: SizeEnum.MEDIUM
        };
      },
      render: function() {
        return (
        <div>
           <a href="#" onClick={this.onSizeChangeClick.bind(this, SizeEnum.SMALL)}>Small</a>
           <a href="#" onClick={this.onSizeChangeClick.bind(this, SizeEnum.MEDIUM)}>Medium</a>
           <a href="#" onClick={this.onSizeChangeClick.bind(this, SizeEnum.LARGE)}>Large</a>
        </div>  
        )
      },

      onSizeChangeClick: function(size, event){
        event.preventDefault();
        this.setState({
          size: size
        });
      }
})