admin管理员组

文章数量:1315072

I have the following react ponent which will be used to toggle a menu:

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 ponent is clicked, I need to toggle it's state so the 'hamburger' icon bees an 'x' icon. I also need to add a prop to the ponent so that the parent menu's state can be updated by listening for 'MenuToggle' ponent to receive the prop. Since I need to do both based on the same click event, I have 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 am calling the single function 'handleClick' which should set / toggle the state of 'MenuToggle', and add the 'whenClicked' prop.

The result is that the state is toggled but 'whenClicked' is not set. whenClicked needs to be set because the parent ponent, 'Menu' listens for 'whenClicked' in 'menuToggle'. When 'Menu' hears 'whenClicked', it fires 'handleClick' which toggles it's 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});
    },
    ponentWillMount: function() {
        this.updateDimensions();
    },
    ponentDidMount: function() {
        $(window).on("resize", this.updateDimensions);
    },
    ponentWillUnmount: 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 the state and set the 'whenClicked' prop with one click event?

I have the following react ponent which will be used to toggle a menu:

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 ponent is clicked, I need to toggle it's state so the 'hamburger' icon bees an 'x' icon. I also need to add a prop to the ponent so that the parent menu's state can be updated by listening for 'MenuToggle' ponent to receive the prop. Since I need to do both based on the same click event, I have 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 am calling the single function 'handleClick' which should set / toggle the state of 'MenuToggle', and add the 'whenClicked' prop.

The result is that the state is toggled but 'whenClicked' is not set. whenClicked needs to be set because the parent ponent, 'Menu' listens for 'whenClicked' in 'menuToggle'. When 'Menu' hears 'whenClicked', it fires 'handleClick' which toggles it's 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});
    },
    ponentWillMount: function() {
        this.updateDimensions();
    },
    ponentDidMount: function() {
        $(window).on("resize", this.updateDimensions);
    },
    ponentWillUnmount: 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 the state and set the 'whenClicked' prop with one click event?

Share Improve this question edited Jun 22, 2015 at 8:09 HelloWorld asked Jun 22, 2015 at 8:00 HelloWorldHelloWorld 2,3303 gold badges31 silver badges47 bronze badges 4
  • 1 It's unclear to me what this.props.whenClicked is supposed to be, since you are not doing anything with it. In general: The owner has to pass a callback to the the ponent and your ponent has to call it. E.g. the owner does <MenuToggle onClick={this.updateSomething} /> and your ponent will do this.props.onClick(). It's the owners responsibility to update its state and rerender and update props accordingly. – Felix Kling Commented Jun 22, 2015 at 8:04
  • OK, I tried to clarify and posted the owner's code too. – HelloWorld Commented Jun 22, 2015 at 8:10
  • Then all you have to do is actually call the function: that.props.whenClicked(). – Felix Kling Commented Jun 22, 2015 at 8:12
  • *facepalm I knew it was some detail I was missing... I copied it out of the inline event originally and didn't think of the changed scope. Thanks! – HelloWorld Commented Jun 22, 2015 at 8:23
Add a ment  | 

2 Answers 2

Reset to default 4

let me see if I can understand this, when clicked:

  1. toggle ponent's state
  2. pass the trigger to parent through props

if the above assumption is true, then here's what I am suggesting:

  1. as for convention, use "on" and "handle" as prefix
  2. classnames could be a good tool to learn since fb is also using it
  3. since set state is async, you can use its call back function to trigger things when the state is set.
  4. pass the new state to its parent is a good practice to let the parent know 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>
        )
    }
});

hope this helps =)

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

本文标签: javascriptHow to set state and props on a single click event in reactjsStack Overflow