将className添加到<div> onClick <a> in ReactJS

时间:2018-03-22 00:52:46

标签: javascript reactjs

I've built a modal in ReactJS which needs to be triggered by clicking an <a> to add .active class to the modal <div className="newsletterModal">.

Once class is active as newsletterModal active the onClick={this.toggle.bind(this)} is successful in removing the active class but how can I add the active class from within my footer?

In Newsletter.js

import React from 'react'
import PropTypes from 'prop-types';
import Link from 'gatsby-link';
class Newsletter extends React.Component {
    constructor(props) {
      super(props);
      this.state = {addClass: false}
    }
    toggle() {
      this.setState({addClass: !this.state.addClass});
    }
    render() {
      let toggleModal = ["newsletterModal"];
      if(this.state.addClass) {
        toggleModal.push('active');
      }
      return(
            <div className={toggleModal.join(' ')}>
                <div className="newsletterContainer">
                   <span className="modalClose">
                       <a onClick={this.toggle.bind(this)} href="javascript:;"><svg>...</svg></a>
                   </span>                       
                   <content /> 
                </div>
            </div>
        );
    }
}
export default Newsletter

In Footer.js (where I want the link to add the class set within Newsletter.js)

import React from 'react'
import PropTypes from 'prop-types';
import Link from 'gatsby-link'
const Footer = (props) => (
    <footer>
        <a onClick={this.toggle.bind(this)} href="javascript:;">
            Newsletter
        </a>        
    </footer>
)
export default Footer

index.js where both are called to the template - please note that I have a class being added to show the menu too from within this file. Perhaps it is possible to combine my is-menu-visible with newsletterModal active?

import React from 'react'
import PropTypes from 'prop-types';
import Helmet from 'react-helmet'
import { Link, withPrefix } from 'gatsby-link'
import '../assets/scss/main.scss'
import Header from '../components/global/Header'
import Menu from '../components/global/Menu'
import Newsletter from '../components/global/Newsletter'
import Footer from '../components/global/Footer'
class Template extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            isMenuVisible: false,
            loading: 'is-loading'
        }
        this.handleToggleMenu = this.handleToggleMenu.bind(this)
    }

    componentDidMount () {
        this.timeoutId = setTimeout(() => {
            this.setState({loading: ''});
        }, 100);
    }

    componentWillUnmount () {
        if (this.timeoutId) {
            clearTimeout(this.timeoutId);
        }
    }

    handleToggleMenu() {
        this.setState({
            isMenuVisible: !this.state.isMenuVisible
        })
    }

    render() {
        const { children } = this.props

        return (
            <main id="app" className={`body ${this.state.loading} ${this.state.isMenuVisible ? 'is-menu-visible' : ''}`}>
                <Helmet>
                    <link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
                </Helmet>
                <div id="wrapper">
                    <div className="sub-wrapper">
                        <Header onToggleMenu={this.handleToggleMenu} />
                        <div className="gutter">
                            {children()}
                            <Footer />
                        </div>
                    </div>
                </div>
                <Menu/>
                <Newsletter />
            </main>
        )
    }
}

Template.propTypes = {
    children: PropTypes.func
}

export default Template

2 个答案:

答案 0 :(得分:1)

可以通过在showActive类中添加Template状态来完成。

Footer中添加回调函数:

const Footer = props => (
  <footer>
    <a onClick={props.onClick}>Newsletter</a>
  </footer>
);

而不是setState,请从addClass

中读取props
class Newsletter extends Component {
  render() {
    let toggleModal = ["newsletterModal"];
    if (this.props.addClass) {
      toggleModal.push("active");
    }
    return (
      <div className={toggleModal.join(" ")}>This part should update!</div>
    );
  }
}

为页脚onClick事件添加事件处理程序:

const Header = props => (
  <header onClick={props.onToggleMenu}>
    <h1>Main Page Title</h1>
  </header>
)

class Template extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showActive: false
    };
  }

  toggleClass = () => {
    this.setState(prevState => ({
      showActive: !prevState.showActive
    }));
  };

  render() {
    return (
      <main>
        <Header onToggleMenu={this.toggleClass} />
        <Newsletter addClass={this.state.showActive} />
        <Footer onClick={this.toggleClass} />
      </main>
    );
  }
}

注意:
如果您有多个组件相互交互,最好考虑使用状态管理器,例如 Redux MobX

<强>更新 我更新了我的代码,所以它可以作为一个完整的演示独立运行 有codesandbox demo link

答案 1 :(得分:0)

您需要将toggle()方法传递给<Footer />组件

import React from 'react'
import PropTypes from 'prop-types';
import Link from 'gatsby-link';
import Footer from './Footer';

class Newsletter extends React.Component {
    constructor(props) {
      super(props);
      this.state = {addClass: false}
    }
    toggle() {
      this.setState({addClass: !this.state.addClass});
    }
    render() {
      let toggleModal = ["newsletterModal"];
      if(this.state.addClass) {
        toggleModal.push('active');
      }
      return(
            <div className={toggleModal.join(' ')}>
                <div className="newsletterContainer">
                   <Footer onClick={this.toggle.bind(this)} />                     
                   <content /> 
                </div>
            </div>
        );
    }
}
export default Newsletter;

在你的Footer.js文件中使用传入的onClick函数作为prop

import React from 'react'
import PropTypes from 'prop-types';
import Link from 'gatsby-link'
const Footer = (props) => (
    <footer>
        <a onClick={this.props.onClick} href="javascript:;">
            Newsletter
        </a>        
    </footer>
)
export default Footer