title: ReactJS Antd Table Rendering Old Data
body: <p><strong>Summary:</strong> I have a component that contains an <code>Antd Table</code> component. The Antd Table component is created initially based on the original <code>userData</code> that is generated using a <code>fetch</code> request. The data is loaded initially and set using <code>setState(fetchedData)</code> calling <code>render()</code> to display appropriately. This works.</p>
  <p>Using the <code>NiceModal</code> library, I present a new modal component and pass in a <code>doCompelte</code> closure that will then <code>setstate</code> again with the updated data. From here, the <code>render()</code> method is called again. I log the updated <code>userData</code> in the <code>render()</code> method before the data is loaded and it shows the data is updated and it confirms that <code>render()</code> is called with the new data. But, the visual display never actually loads on the screen.</p>
  <p>At this point, I stopped taking user input from the Modal and tried giving it direct values, as shown in <strong>EditModal.jsx</strong>. This still doesn't work and I'm unsure of why.</p>
  <p><strong>Question:</strong> Why is my component <code>render()</code> method called, new data printed correctly, but the React Antd Table is not loading the new data?</p>
  <p><strong><em>Note</em></strong>: I did try creating a local variable inside the <code>render()</code> method that accesses <code>userData</code> at that given time but this also doesn't update the table.</p>
  <p><strong>UPDATE 1:</strong> You can see that the first name is <code>&quot;Mrs.&quot;</code> then it gets hardcode changed to <code>&quot;GPRLEJAF&quot;</code> inside the <code>showEditModal()</code> function which now does NOT show a modal, it just changes the value and sets the state.</p>
  <p><a href="https://i.stack.imgur.com/1zihh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1zihh.png" alt="Pre" /></a></p>
  <p>You'll see that the re-rendering shows the update in the console but the table is never updated.</p>
  <p><a href="https://i.stack.imgur.com/csvtb.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/csvtb.jpg" alt="Post" /></a></p>
  <p><strong>UserList.jsx</strong></p>
  <pre class="lang-js prettyprint-override"><code>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 &quot;./Table.css&quot;;
  import 'bootstrap/dist/css/bootstrap.min.css';
  import data from '../../mock';
  
  function search() {
    
  }
  
  function withMyHook(Component) {
    return function WrappedComponent(props) {
      const myHookValue = useLocation();
      return &lt;Component {...props} myHookValue={myHookValue} /&gt;;
    }
  }
  
  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) =&gt; &lt;Button type=&quot;link&quot; icon={&lt;EditOutlined /&gt;} onClick={() =&gt; this.showEditModal(value)}/&gt;
      },
    ];
  
    showEditModal(value) {
      /*
      var index = this.userData.findIndex(item =&gt; item == value);
      NiceModal.show(EditModal,  { data: value, onEdit: (updatedUser) =&gt; {
        this.userData[index] = updatedUser; // Update current user with updated data
        this.setState([...this.userData]); // Re-Render with new data
      }});
      */
      this.userData[0].First_Name = &quot;Random Name&quot;;
      this.setState([this.userData]);
    };
  
    iconStyles = {
      width: '25px',
      fill: '#ffffff',
      justifyContent: 'center',
      alignItems: 'center',
      float: 'left',
      marginRight: '5px',
    };
  
    componentDidMount() {
      console.log(&quot;Updating&quot;);
      const token = this.props.myHookValue.state['token'];
      console.log(&quot;Token&quot;, this.props.myHookValue.state['token']);
      let response = fetch('https://x7n8z7pgo5.execute-api.us-east-1.amazonaws.com/dev', {
        headers: {
          &quot;Authorization&quot;: token
        }
      })
      .then(response =&gt; response.json())
      .then(data =&gt; {
        console.log(&quot;Retrieved Data&quot;, data);
        this.userData = data[&quot;Items&quot;];
        console.log(&quot;User Data&quot;, this.userData);
        this.setState([...data[&quot;Items&quot;]]); //re-renders data
      })
      .catch(err =&gt; console.log(err));
    }
  
    showAddModal = () =&gt; {
      NiceModal.show(AddModal, { component: this });;
    };
  
    render() {
      const curData = this.userData;
      console.log(&quot;Rerendering&quot;, curData);
      return &lt;div&gt;
          &lt;div className=&quot;container-xl&quot;&gt;
              &lt;div className=&quot;table-responsive&quot;&gt;
                  &lt;div className=&quot;table-wrapper&quot;&gt;
                      &lt;div className=&quot;table-title&quot;&gt;
                          &lt;div className=&quot;row&quot;&gt;
                              &lt;div className=&quot;col-sm-6&quot;&gt;
                                  &lt;h2&gt;Manage Clients&lt;/h2&gt;
                              &lt;/div&gt;
                              &lt;div className=&quot;col-sm-6&quot;&gt;
                              {&lt;Button className=&quot;btn btn-success&quot; type=&quot;primary&quot; onClick={this.showAddModal}&gt;
                                &lt;AddCircle style={this.iconStyles}/&gt; Add New Client
                              &lt;/Button&gt;}
                              &lt;/div&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                      &lt;input id=&quot;search&quot; type=&quot;text&quot; placeholder=&quot;Search...&quot; onKeyUp={search}/&gt;
                      &lt;Table
                        size=&quot;small&quot;
                        rowKey=&quot;id&quot;
                        pagination={false}
                        columns={this.columns}
                        dataSource={curData}
                        style={{ marginTop: '20px' }}
                      /&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;div&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
    }
  }
  
  export default withMyHook(UserList);
  </code></pre>
  <p><strong>EditModal.jsx</strong></p>
  <pre class="lang-js prettyprint-override"><code>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 }) =&gt; {
      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 (
          &lt;Dialog
              open={modal.visible}
              onClose={() =&gt; {
              modal.hide();
              }}
              TransitionProps={{
                  onExited: () =&gt; modal.remove(),
              }}
          &gt;
          &lt;DialogTitle id=&quot;edit&quot;&gt;{&quot;Edit Client&quot;}&lt;/DialogTitle&gt;&lt;hr&gt;&lt;/hr&gt;
          &lt;DialogContent&gt;
              &lt;DialogContentText id=&quot;edit_first_name&quot;&gt;
              First Name 
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;TextInput
                  style={textInputStyles()}
                  defaultValue={firstName}
                  onChange={(e) =&gt; setFirstName(e.target.value)}
              /&gt;
              &lt;/DialogContentText&gt;
              &lt;DialogContentText id=&quot;edit_last_name&quot;&gt;
              Last Name 
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;TextInput
                  style={textInputStyles()}
                  defaultValue={lastName}
                  onChange={(e) =&gt; setLastName(e.target.value)}
              /&gt;
              &lt;/DialogContentText&gt;
              &lt;DialogContentText id=&quot;edit_address&quot;&gt;
              Address
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;TextInput
                  style={textInputStyles()}
                  defaultValue={address}
                  onChange={(e) =&gt; setAddress(e)}
              /&gt;
              &lt;/DialogContentText&gt;
              &lt;DialogContentText id=&quot;edit_billed&quot;&gt;
              Billed
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;TextInput
                  style={textInputStyles()}
                  defaultValue={billed}
              /&gt;
              &lt;/DialogContentText&gt;
              &lt;DialogContentText id=&quot;edit_work_date&quot;&gt;
              Work Date
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;TextField
                  id=&quot;date&quot;
                  label=&quot;&quot;
                  type=&quot;date&quot;
                  InputLabelProps={{
                  shrink: true,
                  }}
                  defaultValue={new Date(workDate).toISOString().substring(0, 10)}
              /&gt;
              &lt;/DialogContentText&gt;
              &lt;DialogContentText id=&quot;edit_last_modified_date&quot;&gt;
              Today's Date
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;TextInput
                  style={textInputStyles()}
                  value={new Date().toDateString().split(' ').slice(1).join(' ')}
                  editable={false}
              /&gt;
              &lt;/DialogContentText&gt;
              &lt;DialogContentText id=&quot;edit_notes&quot;&gt;
              Notes
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;TextArea
                  style={textInputStyles(175)}
                  editable={false}
                  defaultValue={notes}
              /&gt;
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              Invoice
              &lt;/DialogContentText&gt;
              &lt;DialogContentText&gt;
              &lt;FilePicker&gt;
                  onClick={}
              &lt;/FilePicker&gt;
              &lt;/DialogContentText&gt;
          &lt;/DialogContent&gt;
          &lt;DialogActions style={{backgroundColor:'#D3D3D3', justifyContent: 'space-between'}}&gt;
              &lt;Button onClick={() =&gt; modal.hide()} className=&quot;btn&quot; style={{backgroundColor:'red', width: '25%'}}&gt;
              Cancel
              &lt;/Button&gt;
              &lt;Button onClick={() =&gt; {
                  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=&quot;btn&quot; style={{backgroundColor: '#47b300', color:'white', width: '25%', float:'right'}}&gt;
              Add
              &lt;/Button&gt;
          &lt;/DialogActions&gt;
          &lt;/Dialog&gt;
      );
  });
  </code></pre>