【问题标题】:Set props as state in child component将 props 设置为子组件中的状态
【发布时间】:2019-12-23 22:31:37
【问题描述】:

这里我想在子组件中设置道具状态。 我有一张填满 ajax 请求的表格。顺便说一句,我正在使用 antd 库。 我的桌子上有一个编辑按钮,应该打开一个包含表单的模式。

父组件

  import React, {Component} from 'react';
import axios from 'axios';
import API from '../../Helpers/Api'
import {Table, Divider, Tag, message, Popconfirm, Icon} from 'antd';
import {
  Card,
  CardBody,
  CardHeader,
  Col,
  Row
} from 'reactstrap';
import EditCountry from './EditCountry'


var token = JSON.parse(localStorage.getItem("token"));
let config = {
  headers: {
    Authorization: token,
    Accept: 'application/json'
  }
}


class ListCountry extends Component {
  constructor(props) {
    super(props);
    this.columns = [
      {
        title: 'نام کشور‌',
        dataIndex: 'name',
        key: 'name',
        // render: text => <a href="javascript:;">{text}</a>,
      },
      {
        title: 'وضعیت',
        dataIndex: 'isForeign',
        key: 'isForeign',
        render: isForeign => (
          <div>
            <Tag color={isForeign ? 'blue' : 'purple'}>
              {isForeign ? 'کشور خارجی است' : 'کشور خارجی نیست'}
            </Tag>

          </div>
        ),
      },
      {
        title: '',
        dataIndex: '',
        key: 'x',
        render: (text, record) =>
          this.state.countries.length >= 1 ? (
            <span>
               <a onClick={() => this.handleEdit(record.key)}>ویرایش کشور</a>
               <Divider type="vertical" />
               <Popconfirm
                 icon={<Icon type="question-circle-o" style={{ color: 'red' }} />}
                 title="آیا از حذف این کشور مطمئن هستید؟"
                 onConfirm={() => this.handleDelete(record.key)}
                 okText="حذف"
                 cancelText="لغو"
               >
                 <a>حذف کشور</a>
              </Popconfirm>
            </span>

          ) : null,
      },
    ];
    this.state = {
      countries: [],
      openModal: false,
      rowId:''
    }
  }

  getCountries = e => {
    var self = this;
    axios.get( API + '/country',
      config
    )
      .then(function (response) {

        const results= response.data.map(row => ({
          key: row._id, // I added this line
          name: row.name,
          isForeign: row.isForeign,
          Id: row._id,
        }))
        self.setState({ countries : results });
      })
      .catch(function (error) {
        console.log(error);
      });
  };
  componentDidMount() {
      this.getCountries();
  }

  handleDelete = id => {
    var self = this;
    axios.delete( API + `/country/${id}`,
      config
    )
      .then(function (response) {
        const countries = [...self.state.countries];
        self.setState({ countries: countries.filter(item => item.key !== id) });
        message.success('عملیات حذف با موفقیت انجام شد.')
      })
      .catch(function (error) {
        console.log(error);
      });
  }

  handleEdit = id => {
    this.setState({
      rowId: id,
      openModal: !this.state.openModal
    })
  }
  render() {
      return (
        <div className="animated fadeIn">
          <Row className="justify-content-center">
            <Col xs="12" md="12">
              <Card>
                <CardHeader>
                  <strong>لیست کشورها</strong>
                </CardHeader>
                <CardBody>
          <Table className="rtl text-right" columns={this.columns} dataSource={this.state.countries}/>
          <EditCountry open={ this.state.openModal } handleEdit= {this.handleEdit} rowId={ this.state.rowId } />
                </CardBody>
              </Card>
            </Col>
          </Row>
        </div>
      )
  }
}

导出默认列表国家;

子组件

    class EditCountry extends Component {

      constructor(props) {
        super(props);
        this.state = {
          id : this.props.rowId
        };
      }

      handleCancel = () => {
          this.props.handleEdit();
      };
      render() {
        return (
          <div>
            <Modal
              title="Basic Modal"
            >
// form
            </Modal>
          </div>
        );
      }
    }

如您所见,我将 props 设置为状态,但 id 为空,我是否遗漏了什么? 提前致谢

【问题讨论】:

  • 你能告诉我们父组件,rowId保存在哪里吗?
  • 是的,更新了我的问题
  • 发布整个组件。
  • 在您的子组件中,改用 props.rowId。
  • 不走运,它是空的,因为起初 rowId 是空的,但在 ajax 请求之后我设置为 rowId

标签: javascript reactjs


【解决方案1】:

您的 rowID 流程如下:

  1. 您将父级的初始状态设置为 rowId = ""
  2. 您将它传递给子组件,它会保存在子状态中
  3. 你这样调用 this.props.handleEdit:this.props.handleEdit();
  4. 您使用 rowId: id in handleEdit 更新您的状态
  5. 父 rowId 不会复制到子 state id,因为它只在组件构造函数中设置。

一开始,rowId 是 "",因为这是你的父级状态中的默认值 => 这将是子级的 id。

问题是,您调用this.props.handleEdit 时没有ID。这会将您的 rowId 设置为在父级中未定义。

您必须在代码中的某处设置 rowId,例如在您的子组件中,如下所示:

 this.props.handleEdit(myID); or this.props.handleEdit(this.state.id);

这将设置 id 和 rowID 将定义为您传递给 handleEdit 的任何内容。

但这不会更新您子组件中状态的 id,因为在父状态更新后不会再次调用构造函数。

要更新子状态,您必须使用 componentDidUpdate 监听 rowId 更改或直接从父组件使用 this.props.rowId。

componentDidUpdate(prevProps) {
  if (this.props.rowId!== prevProps.rowId) {
    this.setState({id: this.props.rowId});
  }
}

希望这会有所帮助。

【讨论】:

  • 是否有任何生命周期方法会在子组件被调用后立即触发?
  • 被叫是什么意思?有componentDidMount和componentDidUpdate。
  • 当我点击表格上的编辑按钮时,我将设置 rowId 并显示模态,也许我可以在此之后将 rowId 道具设置为子状态。
  • 是的,您可以使用 setState 从模态更新您的 id。然后你必须将它传递给 this.props.handleEdit 函数。这将更新父 rowId 状态。
  • 这是我的问题。我想在我的子组件中将 rowId 设置为状态,但我做不到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
  • 2018-09-06
  • 2017-03-04
  • 2018-10-25
  • 2019-07-14
  • 2017-08-11
  • 2017-10-19
相关资源
最近更新 更多