ReactJS Antd表呈现旧数据

gv8xihay  于 2023-02-22  发布在  React
关注(0)|答案(2)|浏览(157)

**摘要:**我有一个包含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>
    );
});
50few1ms

50few1ms1#

Antd Table s require a copy of the data,以便能够动态更新该表。

render() {
    if (typeof this.userData !== 'undefined') {
      var copy = JSON.parse(JSON.stringify(this.userData));
      console.log(copy);
      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={copy}
                        style={{ marginTop: '20px' }}
                      />
                      </div>
                  </div>
                  <div>
              </div>
          </div>
      </div>
    }
    return <div>
      Loading
    </div>
  }
zpgglvta

zpgglvta2#

可能在UserList组件中的componentDidMount和ShowEditModal中(但我们不使用服务器响应格式)

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
      this.setState({userData: data["Items"]}); //re-renders data
      //or
     this.setState({...data["Items"]});
    })
    .catch(err => console.log(err));
  }

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.setState({userData: this.userData});
    //or
    this.setState({...this.userData});
    }});
  };

相关问题