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
答案 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