reactjs - 如何用react js打开动态模态

标签 reactjs react-hooks

我正在尝试将 HTML/Javascript 模式转换为 React js。 在 Reactjs 中,我只想在用户单击“查看项目”按钮时打开模式。 我创建了一个父组件(Portfolio Screen)和一个子组件(Portfolio Modal)。我提供给子组件的数据工作正常,但模态只在第一次打开,然后就打不开了。另一个问题是即使在第一次打开模式时也不会加载数据。

Codesandbox 链接在这里。

https://codesandbox.io/s/reverent-leftpad-lh7dl?file=/src/App.js&resolutionWidth=683&resolutionHeight=675

我也在下面分享了 React 代码。 对于 HTML/JavaScript 代码,这是我之前问过的问题。 How to populate data in a modal Popup using react js. Maybe with hooks

父组件

import React, { useState } from 'react';
import '../assets/css/portfolio.scss';
import PortfolioModal from '../components/PortfolioModal';
import portfolioItems from '../data/portfolio';
const PortfolioScreen = () => {
    const [portfolio, setportfolio] = useState({ data: null, show: false });

    const Item = (portfolioItem) => {
        setportfolio({
            data: portfolioItem,
            show: true,
        });
    };
    return (
        <>
            <section className='portfolio-section sec-padding'>
                <div className='container'>
                    <div className='row'>
                        <div className='section-title'>
                            <h2>Recent Work</h2>
                        </div>
                    </div>
                    <div className='row'>
                        {portfolioItems.map((portfolioItem) => (
                            <div className='portfolio-item' key={portfolioItem._id}>
                                <div className='portfolio-item-thumbnail'>
                                    <img src={portfolioItem.image} alt='portfolio item thumb' />
                                    <h3 className='portfolio-item-title'>
                                        {portfolioItem.title}
                                    </h3>
                                    <button
                                        onClick={() => Item(portfolioItem)}
                                        type='button'
                                        className='btn view-project-btn'>
                                        View Project
                                    </button>
                                </div>
                            </div>
                        ))}
                        <PortfolioModal portfolioData={portfolio} show={portfolio.show} />
                    </div>
                </div>
            </section>
        </>
    );
};

export default PortfolioScreen;

子组件

import React, { useState, useEffect } from 'react';
import { NavLink } from 'react-router-dom';
const PortfolioModal = ({ portfolioData, show }) => {
    const portfolioItem = portfolioData;
    const [openModal, setopenModal] = useState({ showState: false });
    useEffect(() => {
        setopenModal({
            showState: show,
        });
    }, [show]);

    return (
        <>
            <div
                className={`portfolio-popup ${
                    openModal.showState === true ? 'open' : ''
                }`}>
                <div className='pp-inner'>
                    <div className='pp-content'>
                        <div className='pp-header'>
                            <button
                                className='btn pp-close'
                                onClick={() =>
                                    setopenModal({
                                        showState: false,
                                    })
                                }>
                                <i className='fas fa-times pp-close'></i>
                            </button>
                            <div className='pp-thumbnail'>
                                <img src={portfolioItem.image} alt={`${portfolioItem.title}`} />
                            </div>
                            <h3 className='portfolio-item-title'>{portfolioItem.title}</h3>
                        </div>
                        <div className='pp-body'>
                            <div className='portfolio-item-details'>
                                <div className='description'>
                                    <p>{portfolioItem.description}</p>
                                </div>
                                <div className='general-info'>
                                    <ul>
                                        <li>
                                            Created - <span>{portfolioItem.creatDate}</span>
                                        </li>
                                        <li>
                                            Technology Used -
                                            <span>{portfolioItem.technologyUsed}</span>
                                        </li>
                                        <li>
                                            Role - <span>{portfolioItem.Role}</span>
                                        </li>
                                        <li>
                                            View Live -
                                            <span>
                                                <NavLink to='#' target='_blank'>
                                                    {portfolioItem.domain}
                                                </NavLink>
                                            </span>
                                        </li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </>
    );
};

export default PortfolioModal;

最佳答案

Edit vibrant-oskar-y4bfx

您不必使用一个 useState Hook 来保存所有状态。你可以而且我认为你应该把它们分开。在 PortfolioScreen 组件中

const [data, setData] = useState(null);
const [show, setShow] = useState(false);

我将用于将事件投资组合项设置为 toggleItem 的函数 Item 并更改了它的实现

const toggleItem = (portfolioItem) => {
    setData(portfolioItem);
    setVisible(portfolioItem !== null);
  };

你应该在 PortfolioModal 上使用条件渲染,这样你就不需要向它传递一个 show 属性,你将传递一个 closeModal 属性来关闭PortfolioModal 当被点击时

{visible === true && data !== null && (
    <PortfolioModal
        data={data}
        closeModal={() => toggleItem()} // Pass nothing here so the default value will be null and the modal reset
    />
)}

然后在 PortfolioModal 组件中,您需要两个 Prop ,data 和一个 closeModal 函数

const PortfolioModal = ({ data, closeModal }) => {

关闭按钮可以像

<button className="btn pp-close" onClick={closeModal}>
...

关于reactjs - 如何用react js打开动态模态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69204499/

相关文章:

reactjs - 如何测试由在 useEffect 上触发的 SetTimeout 修改的组件样式?

javascript - get/src/components/App.jsx : Unexpected token, 预期 "}"onClick 事件错误

reactjs - React 函数仅在重新访问页面后运行一次

javascript - 设置倒数计时器 React JS

javascript - Javascript : Setting Value to the Object by id,,其中 id 是对象的最后一个字母

javascript - Typescript:TS 编译器不接受使用 bool 类型

reactjs - AWS Amplify - 如何在登录后呈现组件

reactjs - 将联合类型传递给 React 的 useRef 不起作用

javascript - ReactJS:为什么一种状态的值不同?

reactjs - 无法使用数据路由器测试unstable_useBlocker