如何将模式重构为单独的文件?

How do I refactor the modal into a separate file?

抱歉,React 开发新手。我有一个带有弹出模式的有效 React Class 组件。当您点击物品卡片时显示:

import React from 'react';
import {
  Card, Button, CardImg, CardTitle, CardText, CardGroup,
  CardSubtitle, CardBody, CardFooter, CardHeader, CardColumns, CardDeck
} from 'reactstrap';
import Config from 'config';
import { decompressToBase64, formatter } from './common.js'
import "./Item.css";
import Modal from 'react-modal';

const customStyles = {
    content: {
        top: '50%',
        left: '50%',
        right: 'auto',
        bottom: 'auto',
        marginRight: '-50%',
        transform: 'translate(-50%, -50%)',
    },
};

Modal.setAppElement('#root');

class FeaturedCards extends React.Component {
    constructor() {
        super();
        this.state = {
            name: 'React',
            apiData: [],
            isOpen: false
        };        
    }

    async componentDidMount() {
        const tokenString = sessionStorage.getItem("token");
        const token = JSON.parse(tokenString);

        let headers = new Headers({
            "Accept": "application/json",
            "Content-Type": "application/json",
            'Authorization': 'Bearer ' + token.token
        });

        const response = await fetch(Config.apiUrl + `/api/Items/GetFeaturedItems`, {
            method: "GET",
            headers: headers
        });
        const json = await response.json();
        console.log(json);
        this.setState({ itemList: json });
    }   

    render() {
        const items = this.state.itemList;
        let subtitle;

        handleClick = handleClick.bind(this);
        closeModal = closeModal.bind(this);

        function handleClick() {
            this.setState({ isOpen: true });
        }

        function closeModal() {
            console.log('Clicked close button')
            this.setState({ isOpen: false });
        }        

        function afterOpenModal() {
            // references are now sync'd and can be accessed.
            subtitle.style.color = '#f00';
        }

        return (
            <div>
                <CardGroup className="card-group-scroll">
                    {items && items.map(item =>
                        <>
                            <Card key={item.itemNumber} tag="a" onClick={() => handleClick()} style={{ cursor: "pointer" }}>
                                <CardHeader tag="h3">Featured</CardHeader>
                                <CardImg top className="card-picture" src={"data:image/png;base64," + decompressToBase64(item.images[0]?.compressedImageData)} id={item.itemNumber + "Img"} alt={item.itemNumber} />
                                <CardBody className="card-body">
                                    <CardTitle tag="h5">{item.itemNumber}</CardTitle>
                                    <CardSubtitle tag="h6" className="mb-2 text-muted">{item.categoryName}</CardSubtitle>
                                    <CardText className="card-description">{item.itemDescription}</CardText>
                                </CardBody>
                                <CardFooter className="text-muted">{formatter.format(item.price)}</CardFooter>
                            </Card>
                            <Modal
                                isOpen={this.state.isOpen}
                                onAfterOpen={afterOpenModal}
                                onRequestClose={() => closeModal()}
                                style={customStyles}
                                contentLabel={item.itemNumber}>
                                    <h2 ref={(_subtitle) => (subtitle = _subtitle)}>Hello</h2>
                                    <button onClick={() => closeModal()}>close</button>
                                    <div>I am a modal</div>
                                    <form>
                                        <input />
                                        <button>tab navigation</button>
                                        <button>stays</button>
                                        <button>inside</button>
                                        <button>the modal</button>
                                    </form>
                            </Modal>
                        </>
                    )}                
                </CardGroup>
            </div>
        );
    }
}
export default FeaturedCards;

我需要在几个不同的地方使用同一个模式。我需要模式才能访问我单击的项目。如何将模态重构为单独的文件?

如有任何帮助,我们将不胜感激。

更新

我的第一次尝试:

import React from 'react';
import "./Item.css";
import Modal from 'react-modal';

const customStyles = {
    content: {
        top: '50%',
        left: '50%',
        right: 'auto',
        bottom: 'auto',
        marginRight: '-50%',
        transform: 'translate(-50%, -50%)',
    },
};

Modal.setAppElement('#root');

class ItemModal extends React.Component {
    constructor(props) {
        super(props);               
    }

    render() {
        let subtitle;

        closeModal = closeModal.bind(this);

        function closeModal() {
            console.log('Clicked close button')
            this.setState({ isOpen: false });
        }        

        function afterOpenModal() {
            // references are now sync'd and can be accessed.
            subtitle.style.color = '#f00';
        }

        return (
            <Modal
                isOpen={this.state.isOpen}
                onAfterOpen={afterOpenModal}
                onRequestClose={() => closeModal()}
                style={customStyles}
                contentLabel={this.props.item.itemNumber}>
                    <h2 ref={(_subtitle) => (subtitle = _subtitle)}>Hello</h2>
                    <button onClick={() => closeModal()}>close</button>
                    <div>I am a modal</div>
                    <form>
                        <input />
                        <button>tab navigation</button>
                        <button>stays</button>
                        <button>inside</button>
                        <button>the modal</button>
                    </form>
            </Modal>
        );
    }
}
export default ItemModal;

我从FeaturedCards这样调用它<ItemModal item = { item } />

我收到一个错误:TypeError: this.state is null。我似乎无法弄清楚如何从 FeaturedCards...

读取(共享)状态

这是非常基本的(只有打开和关闭功能)示例,说明如何创建通用模式(可能还有其他方法...)。

class ItemModal extends React.Component {
    constructor(props) {
        super(props);               
    }

    render() {
        return (
            <Modal
                isOpen
                onRequestClose={this.props.onRequestClose}
                >
                  Sample content
            </Modal>
        );
    }
}
export default ItemModal;

可以像下面这样使用。

class FeaturedCards extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isOpen: false
        };        
    }

    onRequestClose = () => {
      this.setState({isOpen: false});
    }

    handleClick = () => {
        this.setState({ isOpen: true });
    }

    render() {
      const { isOpen } = this.state;
        return (
            <div>
                <button type="button" onClick={this.handleClick}> open Modal</button>
              { isOpen ? <ItemModal onRequestClose={this.onRequestClose} /> : null }
            </div>
        );
    }
}
export default FeaturedCards;