javascript - 从导航栏打开 React JS 模态
问题描述
所以基本上我想在我的导航栏中使用按钮打开模态。当您在主页上时,您可以在顶部看到导航栏,然后下面是 HeroSection....
这是我的代码:
导航栏.js:
import React, { useState } from 'react';
import { Button } from './Button';
import { Link } from 'react-router-dom';
import './Navbar.css';
import * as openModal from "./HeroSection";
function Navbar() {
const [click, setClick] = useState(false);
const handleClick = () => setClick(!click);
const closeMobileMenu = () => setClick(false);
return (
<>
<nav className='navbar'>
<div className='navbar-container'>
<Link to='/' className='navbar-logo' onClick={closeMobileMenu}>
TRVL
<i class='fab fa-typo3' />
</Link>
<div className='menu-icon' onClick={handleClick}>
<i className={click ? 'fas fa-times' : 'fas fa-bars'} />
</div>
<ul className={click ? 'nav-menu active' : 'nav-menu'}>
<li className='nav-item'>
<Link to='/' className='nav-links' onClick={closeMobileMenu}>
Home
</Link>
</li>
<li className='nav-item'>
<Link
to='/services'
className='nav-links'
onClick={closeMobileMenu}
>
Services
</Link>
</li>
<li className='nav-item'>
<Link
to='/products'
className='nav-links'
onClick={closeMobileMenu}
>
Products
</Link>
</li>
<li className='nav-item'>
<Link
to='/products'
className='nav-links'
onClick={closeMobileMenu}
>
Products
</Link>
</li>
</ul>
<Button onClick={openModal} buttonStyle='btn--outline'>SIGN UP</Button>
</div>
</nav>
</>
);
}
export default Navbar;
HeroSection.js:
import React, {useState} from 'react';
import '../App.css';
import { Button } from './Button';
import './HeroSection.css';
import styled from 'styled-components';
import { Modal } from './Modal';
import { GlobalStyle } from './globalStyles';
const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
`;
function HeroSection() {
const [showModal, setShowModal] = useState(false);
const openModal = () => {
setShowModal(prev => !prev);
};
return (
<Container>
<div className='hero-container'>
<video src='/videos/video-1.mp4' autoPlay loop muted />
<h1>ADVENTURE AWAITS</h1>
<p>What are you waiting for?</p>
<div className='hero-btns'>
<Button
className='btns'
buttonStyle='btn--outline'
buttonSize='btn--large'
>
GET STARTED
</Button>
<Button
className='btns'
buttonStyle='btn--primary'
buttonSize='btn--large'
onClick={openModal}
>
WATCH TRAILER <i className='far fa-play-circle' />
</Button>
</div>
</div>
<Modal showModal={showModal} setShowModal={setShowModal}/>
<GlobalStyle />
</Container>
);
}
export default HeroSection;
模态.js:
import React, { useRef, useEffect, useCallback } from 'react';
import { useSpring, animated } from 'react-spring';
import styled from 'styled-components';
import { MdClose } from 'react-icons/md';
import '../App.css';
const Background = styled.div`
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
position: fixed;
display: flex;
justify-content: center;
align-items: center;
`;
const ModalWrapper = styled.div`
width: 800px;
height: 500px;
box-shadow: 0 5px 16px rgba(0, 0, 0, 0.2);
background: #fff;
color: #000;
display: grid;
grid-template-columns: 1fr 1fr;
position: relative;
z-index: 10;
border-radius: 10px;
`;
const ModalContent = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
line-height: 1.8;
color: #141414;
p {
margin-bottom: 1rem;
}
button {
padding: 10px 24px;
background: #141414;
color: #fff;
border: none;
}
`;
const CloseModalButton = styled(MdClose)`
cursor: pointer;
position: absolute;
top: 20px;
right: 20px;
width: 32px;
height: 32px;
padding: 0;
z-index: 10;
`;
export const Modal = ({ showModal, setShowModal }) => {
const modalRef = useRef();
const animation = useSpring({
config: {
duration: 250
},
opacity: showModal ? 1 : 0,
transform: showModal ? `translateY(0%)` : `translateY(-100%)`
});
const closeModal = e => {
if (modalRef.current === e.target) {
setShowModal(false);
}
};
const keyPress = useCallback(
e => {
if (e.key === 'Escape' && showModal) {
setShowModal(false);
console.log('I pressed');
}
},
[setShowModal, showModal]
);
useEffect(
() => {
document.addEventListener('keydown', keyPress);
return () => document.removeEventListener('keydown', keyPress);
},
[keyPress]
);
return (
<>
{showModal ? (
<Background onClick={closeModal} ref={modalRef}>
<animated.div style={animation}>
<ModalWrapper showModal={showModal}>
<ModalContent>
<img src={"./logo512.png"} className="App-logo" alt="logo" />
</ModalContent>
<CloseModalButton
aria-label='Close modal'
onClick={() => setShowModal(prev => !prev)}
/>
</ModalWrapper>
</animated.div>
</Background>
) : null}
</>
);
};
我尝试链接导航栏中的 SIGN UP 按钮以在我的 HeroSection 中执行“openModal”功能,并希望它会执行代码并在主页上打开 Modal。谁能帮我解决这个问题?谢谢!
解决方案
我认为您不应该像这样从另一个组件调用组件的函数。openModal
在 react 上执行此操作的方法是从props
a传递函数parent component
。
例如:
父.js
/**
* Component that holds all three components
*/
function Parent() {
const [isModalOpen, setModalOpen] = useState(false);
const openModal = () => {
setModalOpen(true);
}
const closeModal = () => {
setModalOpen(false);
}
return (
<>
<NavBar openModal={openModal} />
<HeroSection />
<Modal isOpen={isModalOpen} close={closeModal} />
</>
)
}
所以你的导航栏可以使用传递的功能
导航栏.js
function Navbar({ openModal }) {
...
return (
<Button onClick={openModal} buttonStyle='btn--outline'>SIGN UP</Button>
)
}
模态使用父级的状态是否出现
模态.js
function Modal({ isOpen, close }) {
return (
<>
{ isOpen ? (
<Background onClick={close} ref={modalRef}></Background>
...
) : null}
</>
)
}
我强烈建议你阅读官方的 react 文档
推荐阅读
- android - 与 Rest Api 问题的移动应用程序连接
- c# - Linq ToLookUp 太慢了
- reactjs - React|Webpack4|Babel7 模块构建失败
- python - 我可以使用 pandas 从我的数据框中创建这种 json 格式吗?
- android - 如何将项目高音移植到设备?
- docker - 无法使用 docker (prom/prometheus) 加载 prometheus.yml 配置文件
- angularjs - 视图模板未使用 $routeProvider 呈现
- python - 解析文本文件不同行的有效方法
- android - Firebase 跟踪显示错误的中位时间延迟?
- python - 如何将边界框六进制值转换为整数?