将道具设置为子组件中的状态

时间:2019-08-18 11:53:51

标签: javascript reactjs

在这里我想设置道具以在子组件中陈述。 我有一张桌子,上面充满了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>
      )
  }
}

导出默认ListCountry;

子组件

    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>
        );
      }
    }

如您所见,我将道具设置为状态,但是id为空,我错过了什么吗? 预先感谢

1 个答案:

答案 0 :(得分:1)

您的rowID流程如下:

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

开头,rowId为“”,因为这是您父级状态的默认值=>这将是子级的ID。

问题是,您在没有ID的情况下呼叫this.props.handleEdit。这样会将您的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});
  }
}

希望这会有所帮助。