Reputation: 318
Here i want to set props to state in child component. I have a table that fill with ajax request. btw I'm using antd library. 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;
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 ?
Thanks in advance
Upvotes: 0
Views: 298
Reputation: 8774
Your flow for rowID is like this:
this.props.handleEdit();
At the beginning, rowId is "", because that is the default in your state of the parent => This will be the id of the child.
The problem is, that you call this.props.handleEdit
without an id. This will set your rowId to be undefined in the parent.
You have to set the rowId somewhere in your code, for example in your child component like this:
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.
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.
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(prevProps) {
if (this.props.rowId!== prevProps.rowId) {
this.setState({id: this.props.rowId});
}
}
Hope this helps.
Upvotes: 1