将OnClick事件从组件传递到其他组件

时间:2019-12-12 06:13:46

标签: javascript reactjs gatsby

我们说有两个组成部分header.jslayout.js

// header.js

import React from 'react';

class Header extends React.Component {

   state = { showMenu: false }

    toggleMenu = () => {
        this.setState({
            showMenu: !this.state.showMenu
        })
   }

   render() {
        const menuActive = this.state.showMenu ? 'active' : '';
        const buttonActive = this.state.showMenu ? 'active' : '';

        return (

            <button className={`button ${buttonActive}`} onClick={this.toggleMenu}>
              Some Button
            </button>
            <div className={`menu ${menuActive}`}>
                ...
            </div>
        )
   }
}

export default Header
// layout.js

import React from 'react';
import Header from './header';

const Layout = (props) => {
  <div className="foo"> // <==== need to add class from onClick event in header.js
     <Header/>
     <main>
       {props.children}
     </main>
  </div>
}

export default Layout

动机

如您所见,我已经成功地在onClick中创建了header.js事件,但是另一方面,我还需要将该事件传递给layout.js,以便我可以添加一些其他类。也许可以使用props完成此操作,不幸的是,由于我是React的新手,所以我不知道如何将其实现到代码中

2 个答案:

答案 0 :(得分:2)

我有一个简单的解决方案。

您可以在父组件上声明状态和功能。

在您的代码中,您只需在Layout上声明它们即可。


header.js

import React from 'react';

class Header extends React.Component {

   /* state = { showMenu: false }
   toggleMenu = () => {
        this.setState({
            showMenu: !this.state.showMenu
        })
   }*/

   render() {
        // const menuActive = this.state.showMenu ? 'active' : '';
        // const buttonActive = this.state.showMenu ? 'active' : '';
        const menuActive = this.props.showMenu ? 'active' : '';
        const buttonActive = this.props.showMenu ? 'active' : '';
        return (

            <button className={`button ${buttonActive}`} onClick={this.props.toggle}>
              Some Button
            </button>
            <div className={`menu ${menuActive}`}>
                ...
            </div>
        )
   }
}

export default Header

layout.js

import React from 'react';
import Header from './header';

const Layout = (props) => { 
  const [showMenu, setShowMenu] = React.useState(false);
  const toggle = () => setShowMenu(!showMenu); 
return(
  <div className={`foo ${showMenu? 'active':''}`}> // <==== need to add class from onClick event in header.js
     <Header showMenu={showMenu} toggle={toggle}/>
     <main>
       {props.children}
     </main>
  </div>
)
}    
export default Layout

还有其他一些选择

ReduxMobx ...

如果要构建复杂而庞大的应用程序,则应使用其中之一。

答案 1 :(得分:1)

您应该控制Layout组件中的状态,并将toggleMenu回调作为prop传递到Header组件:

// header.js
import React from 'react';

const Header = ({ menuActive, toggleMenu}) => {
  return (
    <button className={`button ${menuActive}`} onClick={toggleMenu}>
      Some Button
    </button>
    <div className={`menu ${menuActive}`}>
      ...
    </div>
  )
}

export default Header
// layout.js

import React from 'react';
import Header from './header';

class Layout extends React.Component {
  state = { showMenu: false }

  toggleMenu = () => {
    this.setState({
      showMenu: !this.state.showMenu
    })
  }

  render() {
    const menuActive = this.state.showMenu ? 'active' : '';

    return (
      <div className={`foo ${menuActive}`}>
       <Header menuActive={menuActive} toggleMenu={this.toggleMenu} />
       <main>
         {this.props.children}
       </main>
      </div>
    )
  }
}
export default Layout