How to set state and props to one click event in react

I have the following react component that will be used to switch menus:

var MenuToggle = React.createClass({
    render: function() {
        return(
            <a id="menu-toggle" href="javascript:void(0);">
                <i id="closed" className="fa fa-bars"></i>
                <i id="open" className="fa fa-times"></i>
            </a>
        )
    }
});

      

When this component is clicked, I need to toggle it so that the hamburger icon becomes an "x" icon. I also need to add a prop to the component so that the state of the parent menu can be updated by listening to the "MenuToggle" component to get the prop. Since I need to do both based on the same click event, I tried:

var MenuToggle = React.createClass({
    getInitialState: function() {
        return {open: false}
    },
    handleClick: function() {
        var that = this;
        function setTheState() {
            that.setState({open: !that.state.open})
        }
        function setTheProps() {
            that.props.whenClicked
        }
        setTheState()
        setTheProps()
    },
    render: function() {
        return(
            <a id="menu-toggle" href="javascript:void(0);" onClick={this.handleClick} className={(this.state.open ? 'open' : '')}>
                <i id="closed" className="fa fa-bars"></i>
                <i id="open" className="fa fa-times"></i>
            </a>
        )
    }
});

      

Basically, I call the only function "handleClick", which should set / toggle the state of "MenuToggle" and add "whenClicked".

As a result, the state is toggled, but "whenClicked" is not set. whenClicked must be set because the parent Menu component is listening for whenClicked on menuToggle. When Menu hears "WhenClicked", it triggers "handleClick", which toggles its own state:

var Menu = React.createClass({

    getInitialState: function() {
        return {open: false, mobi: false}
    },
    handleClick: function() {
        this.setState({open: !this.state.open})
    },
    closeOnMobiScroll: function() {
        /*
        if(this.state.mobi === false) {
            this.setState({open: false})
        }
        */
    },
    updateDimensions: function() {
        $(window).width() >= 767 ? this.setState({mobi: true}) : this.setState({mobi: false});
    },
    componentWillMount: function() {
        this.updateDimensions();
    },
    componentDidMount: function() {
        $(window).on("resize", this.updateDimensions);
    },
    componentWillUnmount: function() {
        $(window).on("resize", this.updateDimensions);
    },
    render: function() {
        return (
            <div id="menu-wrap">
                <MenuToggle whenClicked={this.handleClick} />
                <div id="menu" className={(this.state.open ? 'open' : '')} >
                    <MenuTitle />
                    <MenuList whenClicked={this.handleClick}/>
                </div>
            </div>
        )
    }

});

      

Is there a way to toggle state and set prop 'whenClicked' with one click event?

+3


source to share


2 answers


Let me see if I can figure it out when we click:

  • enable component state
  • pass the trigger to parents via props

if this assumption is correct, then this is what I suggest:

  • as for convention, use "on" and "handle" as a prefix
  • classnames can be a good learning tool as fb uses it too
  • since the state is set isync, you can use its callback function to trigger things when the state is set.
  • transferring the new state to your parent is a good practice so that the parent knows the child's state


here's the modified version:

var MenuToggle = React.createClass({
    getInitialState: function() {
        return {
            isOpen: false
        };
    },
    _handleClick: function(e) {
        e.preventDefault();
        this.setState({isOpen: !this.state.isOpen}, function() {
            this.props.onClick(this.state.isOpen);
        });
    },
    render: function() {
        var iconClass = classNames('fa', this.state.isOpen ? 'fa-times' : 'fa-bars');
        return(
            <a id="menu-toggle" onClick={this._handleClick}>
                <i className={iconClass}></i>
            </a>
        )
    }
});
      

Run codeHide result


hope this helps =)

+3


source




var MenuToggle = React.createClass({
    getInitialState: function() {
        return {
            isOpen: false
        };
    },
    _handleClick: function(e) {
        e.preventDefault();
        this.setState({isOpen: !this.state.isOpen}, function() {
            this.props.onClick(this.state.isOpen);
        });
    },
    render: function() {
        var iconClass = classNames('fa', this.state.isOpen ? 'fa-times' : 'fa-bars');
        return(
            <a id="menu-toggle" onClick={this._handleClick}>
                <i className={iconClass}></i>
            </a>
        )
    }
});
      

Run codeHide result


0


source







All Articles