简体   繁体   English

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

[英]Set props as state in child component

Here i want to set props to state in child component. 在这里我想设置道具来说明子组件。 I have a table that fill with ajax request. 我有一张桌子,上面充满了ajax请求。 btw I'm using antd library. 顺便说一句,我正在使用antd库。 there is an Edit button on my table that should open a modal that contains a form. 我的桌子上有一个“编辑”按钮,应打开一个包含表单的模式。

Parent Component 父组件

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

export default ListCountry; 导出默认的ListCountry;

Child Component 子组件

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

so as you see i'm setting props as state but the id is empty, am i missing something ? 因此,如您所见,我将道具设置为状态,但id为空,我是否缺少某些东西? Thanks in advance 提前致谢

Your flow for rowID is like this: 您的rowID流程如下所示:

  1. You set the initial state of the parent to be rowId = "" 您将父级的初始状态设置为rowId =“”
  2. You pass that to the child component and it gets saved in the child state 您将其传递给子组件,它将以子状态保存
  3. You call this.props.handleEdit like this: this.props.handleEdit(); 您可以这样调用this.props.handleEdit: this.props.handleEdit();
  4. You update your state with rowId: id in handleEdit 您可以在handleEdit中使用rowId:id更新状态
  5. The parent rowId will not copied to the child state id because it is only set in the component constructor. 父rowId不会复制到子状态ID,因为它仅在组件构造函数中设置。

At the beginning, rowId is "", because that is the default in your state of the parent => This will be the id of the child. 一开始,rowId为“”,因为这是父级状态的默认值=>这将是子级的ID。

The problem is, that you call this.props.handleEdit without an id. 问题是,您this.props.handleEdit没有id的情况下调用this.props.handleEdit This will set your rowId to be undefined in the parent. 这会将您的rowId设置为在父级中未定义。

You have to set the rowId somewhere in your code, for example in your child component like this: 您必须在代码中的某处设置rowId,例如在您的子组件中,如下所示:

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

This will set the id and rowID will be defined to whatever you pass to handleEdit. 这将设置id,并将rowID定义为传递给handleEdit的任何对象。

But this will not update your id in your state within your child component, since the constructor will not be called again after the parent state updates. 但这不会在子组件内的状态下更新您的id,因为在父状态更新后不会再次调用构造函数。

To update the child state, you will have to listen to rowId changes with componentDidUpdate or use this.props.rowId directly from the parent component. 要更新子状态,您将必须使用componentDidUpdate监听rowId的更改,或直接从父组件使用this.props.rowId。

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

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM