**摘要:**我有一个包含Antd Table
组件的组件。Antd Table组件最初是基于使用fetch
请求生成的原始userData
创建的。数据最初是使用setState(fetchedData)
调用render()
进行加载和设置的,以便适当地显示。这样可以正常工作。
使用NiceModal
库,我提供了一个新的模态组件,并传入一个doCompelte
闭包,然后使用更新后的数据再次执行setstate
。再次调用render()
方法。在加载数据之前,我在render()
方法中记录了更新的userData
,它显示数据已更新,并确认render()
调用新的数据。但是,视觉显示从来没有真正加载到屏幕上。
此时,我停止了从Modal获取用户输入,并尝试给它直接的值,如EditModal.jsx中所示。
**问题:**为什么调用了组件render()
方法,正确打印了新数据,但React Antd表未加载新数据?
注意:我确实尝试在render()
方法中创建一个局部变量,该变量在给定时间访问userData
,但这也不会更新表。
**更新1:**您可以看到,第一个名称是"Mrs."
,然后在showEditModal()
函数中将其硬编码更改为"GPRLEJAF"
,该函数现在不显示模态,它只是更改值并设置状态。
您将看到重新呈现在控制台中显示更新,但表从未更新。
用户列表.jsx
import React, { useEffect } from 'react';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { Button, Table } from 'antd';
import { EditOutlined } from '@ant-design/icons';
import AddCircle from '../../../node_modules/material-jsx-icons/dist/icons/add_circle';
import { useLocation } from 'react-router-dom';
import AddModal from './AddModal'
import EditModal from './EditModal'
import "./Table.css";
import 'bootstrap/dist/css/bootstrap.min.css';
import data from '../../mock';
function search() {
}
function withMyHook(Component) {
return function WrappedComponent(props) {
const myHookValue = useLocation();
return <Component {...props} myHookValue={myHookValue} />;
}
}
class UserList extends React.Component {
constructor(props) {
super(props);
this.state = {
userData: [],
}
}
self = this;
columns = [
{
title: 'First Name',
dataIndex: 'First_Name',
width: '10%',
align: 'center',
},
{
title: 'Last Name',
dataIndex: 'Last_Name',
width: '10%',
align: 'center',
},
{
title: 'Address',
dataIndex: 'Address',
width: '20%',
align: 'center',
},
{
title: 'Billed',
dataIndex: 'Billed',
width: '5%',
align: 'center',
},
{
title: 'Work Date',
dataIndex: 'Work_Date',
width: '12%',
align: 'center',
},
{
title: 'Last Modified Date',
dataIndex: 'Table_Date',
width: '12%',
align: 'center',
},
{
title: 'Notes',
dataIndex: 'Notes',
width: '32%',
align: 'center',
},
{
title: 'Actions',
width: '5%',
align: 'center',
dataIndex: 'taco',
render: (_, value) => <Button type="link" icon={<EditOutlined />} onClick={() => this.showEditModal(value)}/>
},
];
showEditModal(value) {
/*
var index = this.userData.findIndex(item => item == value);
NiceModal.show(EditModal, { data: value, onEdit: (updatedUser) => {
this.userData[index] = updatedUser; // Update current user with updated data
this.setState([...this.userData]); // Re-Render with new data
}});
*/
this.userData[0].First_Name = "Random Name";
this.setState([this.userData]);
};
iconStyles = {
width: '25px',
fill: '#ffffff',
justifyContent: 'center',
alignItems: 'center',
float: 'left',
marginRight: '5px',
};
componentDidMount() {
console.log("Updating");
const token = this.props.myHookValue.state['token'];
console.log("Token", this.props.myHookValue.state['token']);
let response = fetch('https://x7n8z7pgo5.execute-api.us-east-1.amazonaws.com/dev', {
headers: {
"Authorization": token
}
})
.then(response => response.json())
.then(data => {
console.log("Retrieved Data", data);
this.userData = data["Items"];
console.log("User Data", this.userData);
this.setState([...data["Items"]]); //re-renders data
})
.catch(err => console.log(err));
}
showAddModal = () => {
NiceModal.show(AddModal, { component: this });;
};
render() {
const curData = this.userData;
console.log("Rerendering", curData);
return <div>
<div className="container-xl">
<div className="table-responsive">
<div className="table-wrapper">
<div className="table-title">
<div className="row">
<div className="col-sm-6">
<h2>Manage Clients</h2>
</div>
<div className="col-sm-6">
{<Button className="btn btn-success" type="primary" onClick={this.showAddModal}>
<AddCircle style={this.iconStyles}/> Add New Client
</Button>}
</div>
</div>
</div>
<input id="search" type="text" placeholder="Search..." onKeyUp={search}/>
<Table
size="small"
rowKey="id"
pagination={false}
columns={this.columns}
dataSource={curData}
style={{ marginTop: '20px' }}
/>
</div>
</div>
<div>
</div>
</div>
</div>
}
}
export default withMyHook(UserList);
编辑模态.jsx
import { Modal } from 'antd';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import { FilePicker, TextInput } from 'evergreen-ui';
import TextArea from 'antd/lib/input/TextArea';
import TextField from '@material-ui/core/TextField';
import { Button } from 'antd';
import React, { useState } from 'react';
function textInputStyles(height='40px') {
return {
width: '350px',
fontSize: '20px',
height: height,
}
}
export default NiceModal.create(({ data, onEdit }) => {
const user = data;
const [firstName, setFirstName] = useState(user.First_Name);
const [lastName, setLastName] = useState(user.Last_Name);
const [address, setAddress] = useState(user.Address);
const [billed, setBilled] = useState(user.Billed);
const [workDate, setWorkDate] = useState(user.Work_Date);
const [notes, setNotes] = useState(user.Notes);
const modal = useModal();
return (
<Dialog
open={modal.visible}
onClose={() => {
modal.hide();
}}
TransitionProps={{
onExited: () => modal.remove(),
}}
>
<DialogTitle id="edit">{"Edit Client"}</DialogTitle><hr></hr>
<DialogContent>
<DialogContentText id="edit_first_name">
First Name
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</DialogContentText>
<DialogContentText id="edit_last_name">
Last Name
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</DialogContentText>
<DialogContentText id="edit_address">
Address
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={address}
onChange={(e) => setAddress(e)}
/>
</DialogContentText>
<DialogContentText id="edit_billed">
Billed
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={billed}
/>
</DialogContentText>
<DialogContentText id="edit_work_date">
Work Date
</DialogContentText>
<DialogContentText>
<TextField
id="date"
label=""
type="date"
InputLabelProps={{
shrink: true,
}}
defaultValue={new Date(workDate).toISOString().substring(0, 10)}
/>
</DialogContentText>
<DialogContentText id="edit_last_modified_date">
Today's Date
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
value={new Date().toDateString().split(' ').slice(1).join(' ')}
editable={false}
/>
</DialogContentText>
<DialogContentText id="edit_notes">
Notes
</DialogContentText>
<DialogContentText>
<TextArea
style={textInputStyles(175)}
editable={false}
defaultValue={notes}
/>
</DialogContentText>
<DialogContentText>
Invoice
</DialogContentText>
<DialogContentText>
<FilePicker>
onClick={}
</FilePicker>
</DialogContentText>
</DialogContent>
<DialogActions style={{backgroundColor:'#D3D3D3', justifyContent: 'space-between'}}>
<Button onClick={() => modal.hide()} className="btn" style={{backgroundColor:'red', width: '25%'}}>
Cancel
</Button>
<Button onClick={() => {
modal.hide();
const updatedUser = {
'Address': 'asd',
'First_Name': 'asd',
'Billed': '123',
'Index': user.Index,
'Last_Name': 'fadsad',
'Notes': 'sdad',
'Table_Date': new Date(workDate).toISOString().substring(0, 10),
'Work_Date': workDate
};
onEdit(updatedUser);
}} className="btn" style={{backgroundColor: '#47b300', color:'white', width: '25%', float:'right'}}>
Add
</Button>
</DialogActions>
</Dialog>
);
});
2条答案
按热度按时间50few1ms1#
Antd Table
s require a copy of the data,以便能够动态更新该表。zpgglvta2#
可能在UserList组件中的componentDidMount和ShowEditModal中(但我们不使用服务器响应格式)