【问题标题】:How to open dynamic modal with react js如何使用 React js 打开动态模式
【发布时间】:2021-09-16 07:58:46
【问题描述】:

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

代码沙盒链接在这里。

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;

【问题讨论】:

  • 您在 Codesandbox 或 jsfiddle 中有运行示例吗?我们会更容易提供帮助
  • 我没有,让我尝试添加到您提到的上述之一
  • 您能提供一些投资组合数据吗? @JohnZampa。来自"../data/portfolio"
  • @CuongVu 这是 Codesandbox 链接。 codesandbox.io/s/reverent-leftpad-lh7dl?file=/src/…
  • @a.mola 我分享了codesandbox.io,可以查看代码。

标签: reactjs react-hooks


【解决方案1】:

您不必使用一个useState 挂钩来保存所有状态。你可以,我认为你应该把它们分开。在PortfolioScreen component

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

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

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 组件中,您需要两个 props,data 和一个 closeModal 函数

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

关闭按钮可以是这样的

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

【讨论】:

  • 感谢您的错字更正,但我使用portfolioItem !== null 只是作为额外检查,因为PortfolioModal 应该仅在数据设置或不为空时可见。当然你可以使用!visible,但它不提供安全性。请不要忘记接受答案。这意味着很多@JohnZampa
猜你喜欢
  • 1970-01-01
  • 2015-11-23
  • 2016-10-19
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多