Change component state on button click

后端 未结 4 1319
夕颜
夕颜 2020-12-06 19:11

The following is the HTML.



        
相关标签:
4条回答
  • 2020-12-06 19:40

    You can't set the state of a React component like that. And the component should be responsible for setting its own state.

    Inside your Board component, set up event listeners in componentDidMount. The best solution would be to let the buttons be part of the React application, but that's beyond the scope of this question. So let's say that the buttons are not part of the React application, then do something like this:

    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(){
        ...
        ...
      }
    });
    

    Then just move all that componentWillMount style stuff to the render function.

    Update

    Fiddle: https://jsfiddle.net/dannyjolie/r525ux66/

    0 讨论(0)
  • 2020-12-06 19:49

    You should not change state of React component directly. Use setState function instead. When you call setState React will re-render compoment.

    Add new function setSize to your Board compoment:

        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);
            }
          }
    
    0 讨论(0)
  • 2020-12-06 19:50

    This is an anti pattern though this is the right way to achieve what you are looking for.

    Since ReactDOM.render returns an instance of the component that is rendered, you can use that and update it's state.

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

    The right way to do this, is to make buttons components of Board and attach event handlers on them eg :

    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
            });
          }
    })
    
    0 讨论(0)
  • 2020-12-06 19:51

    You are taking the wrong approach. The hardest part about react is "Thinking in React." If you want things to work properly, the notion of reaching into the DOM directly, like you are doing with document.getElementById, is off the table.

    The simplest way for you to get started is to render your button inside the render function of your Board component. Then you can put a click handler inside the Board component to set the state.

    This should get you started:

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

    Once you get this working, if you want to separate your button from your button, then you will want to look into using a Flux implementation to pass state from component to component.

    0 讨论(0)
提交回复
热议问题