简体   繁体   English

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

[英]Pass OnClick event from component to other component

Lets say there is 2 component header.js and layout.js比方说,有2个分量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

motivation动机

As you can see I have managed to create onClick event in the header.js but in the other hand i also need to pass the event to layout.js so i can add some additional class.正如你所看到的,我已经成功地在header.js创建了onClick事件,但另一方面,我还需要将事件传递给layout.js以便我可以添加一些额外的类。 Maybe this can be done using props , unfortunately since i new in React i have no idea how to implement it into the code也许这可以使用props来完成,不幸的是因为我是 React 新手,我不知道如何将它实现到代码中

I have a simple solution.我有一个简单的解决方案。

You can declare the state and function on the parent component.您可以在父组件上声明状态和函数。

in your code, you just declare them on Layout .在您的代码中,您只需在Layout上声明它们。


header.js头文件.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布局.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

And, there're some other options而且,还有一些其他选择

ie Redux , Mobx ...ReduxMobx ...

If you are going to build a complicated and huge application, you should use one of them.如果您要构建一个复杂而庞大的应用程序,您应该使用其中之一。

You should control the state in the Layout component, and pass the toggleMenu callback as a prop to the Header component:您应该控制 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM