我有一个PersonList组件,无论用户在何处单击List.Item,我都希望将诸如personId的一些详细信息传递给PersonModal并显示它。我正在使用Ant Design组件进行模态设计。

以下是我尝试过的方法,但不幸的是我遇到了类似的错误:


  警告:无法在尚未安装的组件上调用setState。
  这是一项禁止操作,但可能表明您的应用程序中存在错误。
  而是直接分配给this.state或定义state = {};
  在PersonModal组件中具有所需状态的class属性。


PersonModal.js

import React from "react";
import {Modal} from "antd";

class PersonModal extends React.Component {
    constructor(props) {
        super(props);
        console.log(this.props.personId)
    }

    state = { visible: false };

    showModal = () => {
        this.setState({
            visible: true,
        });
    };

    // handleOk (...)
    // handleCancel (...)

    render() {
        return <Modal
            title="Basic Modal"
            visible={this.state.visible}
            onOk={this.handleOk}
            onCancel={this.handleCancel}
        >
            Modal body
        </Modal>
    }
}
export default PersonModal;


PersonList.js

import React from "react";
import {Icon, Input, List, Avatar} from "antd";
import PersonModal from "PersonModal/PersonModal"

class PersonList extends React.Component {

    showModal(personId) {
        const modal = new PersonModal({personId: 123})
        modal.showModal()
    }

    render() {
        const persons = this.props.list;
        return (
            <div>
            <List
                itemLayout="horizontal"
                dataSource={persons}
                renderItem={item => (
                    <>
                    <List.Item onClick={this.showModal(123)} style={{cursor: 'pointer'}}>
                        <List.Item.Meta
                            avatar={<Avatar src="avatar.png"/>}
                            title={<span>{item.firstName} {item.lastName}</span>}
                            description={<span>{item.city}, {item.country}</span>}
                        />
                    </List.Item>
                    </>
                )}
            />
            </div>
        );
    }
}


解决该问题的正确方法是什么?由于我是React的新手,所以我认为这不是正确的方法。

stackblitz here上的转载问题

最佳答案

您需要在PersonList组件中跟踪PersonModal的可见状态。您应该有一个布尔变量来控制PersonModal的可见性。

而PersonModal将不控制其可见性状态,而是从其客户端获取它的状态,在这种情况下,客户端是PersonList。让我们从代码开始

首先,编辑PersonModal组件以期望其客户端提供道具

class PersonModal extends React.Component {
    // handleOk (...)
    // handleCancel (...)

    handleCancel = () => {

        // because the client controls the visivlity state of the component
        this.props.hideModal();
    }

    render() {
         /// this.props.isVisible is required, and it will be a boolean true or false.
        const shouldBeVisible = this.props.isVisible;

        return <Modal
            title="Basic Modal"
            visible={shouldBeVisible}
            onOk={this.handleOk}
            onCancel={this.handleCancel}
        >
            Modal body
        </Modal>
    }
}
export default PersonModal;



现在,您的PersonModal组件将扩展一个prop;这是可见的道具。


class PersonList extends React.Component {

    state = {
        // the client controls the visibility of the modal with this state key;
        showModal: false,
        personId: null
    }


    // edited
    showModal = (personId) => {
       // set state to update the UI and show the PersonModal
        this.setState({
            showModal: true,
            personId: personId
        });
    }

     hideModal= () => this.setState({showModal: false});

    render() {
        const persons = this.props.list;
        return (
            <div>
             // now PersonModal will only be visible when the parent of it tells it to
            <PersonModal
            isVisible = {this.state.showModal}
                hideModal= {this.hideModal}
/>
            <List
                itemLayout="horizontal"
                dataSource={persons}
                renderItem={item => (
                    <>
                    <List.Item onClick={() => this.showModal(123)} style={{cursor: 'pointer'}}>
                        <List.Item.Meta
                            avatar={<Avatar src="avatar.png"/>}
                            title={<span>{item.firstName} {item.lastName}</span>}
                            description={<span>{item.city}, {item.country}</span>}
                        />
                    </List.Item>
                    </>
                )}
            />
            </div>
        );
    }
}


希望对您有帮助;

这就是React世界中解决问题的方式

09-11 14:08