0

I am learning about React and right now I am on Lifecycle Hooks. How can I stop my component re-rendering data into the table with each page reload? Right now I am getting duplicated or empty row data in the table. Also data does not appear until I user the Sharepoint Discard method in the workbench.

My Component is below:

import * as React from 'react';
import styles from './AZ.module.scss';
import { IAZProps } from './IAZProps';
import { escape } from '@microsoft/sp-lodash-subset';

import {
  SPHttpClient,
  SPHttpClientResponse,
  ISPHttpClientOptions    
} from '@microsoft/sp-http';
import { IListItem } from './IListItem';
import * as ReactDom from 'react-dom';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField,
  PropertyPaneCheckbox,
  PropertyPaneDropdown,
  PropertyPaneToggle,
  IWebPartContext
} from '@microsoft/sp-webpart-base';

//Datatables
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';
import PanelA  from './CompNote';
import PanelB from './CompNoteBoard'

export interface ISPLists {
  value: ISPList[];
}

export interface ISPList {
  Id: string;
  Title: string;
  Office_x0020_Type: string;
  Path: string;
}


//local data
var products = [{
      id: 1,
      name: "Product1",
      price: 120
  }, {
      id: 2,
      name: "Product2",
      price: 80
  }];

  var productsGlobal = [{
    id: '',
    title: '',
    location: ''}];

var myAPIList = [];
var faker = require('faker');
var externalData = faker;

export interface INpmsharepoint2State {
 // isOpen: Boolean;
 myAPIList;
}

export default class AZ extends React.Component<IAZProps, INpmsharepoint2State> {

      private spHttpClient: SPHttpClient;
      private contacts: ISPLists[];
      private webAbsoluteUrl: string;

      constructor(props) {
        super(props);
        this.state = { myAPIList:  []}; 


}//constructor

componentDidMount() {

}

componentWillMount(){
  }

public render(): React.ReactElement<IAZProps> {

  var nameArray = [];
  var dataArray = [];
  var fitems = [];
  var tableColumn: any;

  this.props.spHttpClient.get(`${this.props.siteUrl}/sites/dev-sm/_api/web/lists/GetByTitle('CourseBookingTest')/items`,
  SPHttpClient.configurations.v1,
    {
      headers: {
        'Accept': 'application/json;odata=nometadata',
        'odata-version': ''
      }
    })
    .then((response: SPHttpClientResponse): Promise<{ value: IListItem[] }> => {
      //alert(`Successfully loaded ` + response.json() + ` items`);
      return response.json();
    })
    .then((response: { value: IListItem[] }) => {

        alert(`Successfully loaded ` + response.value.length + ` items`);

        //1 Response value to fitmes
        fitems = response.value

        //1 for each of response item push to data array
        //2 still json object so not string
         for(var i=0;i<fitems.length;i++){
           dataArray.push(fitems[i]);
           console.log(fitems[i]); 
        }

       //map the json object to another array and
       //via each object key so it's stringable
       //and can be sent to browser
       nameArray =  dataArray.map(function(item){
         //alert(item.Id); 
            //alert(data2[0].title);
               return {
               value: item.Title, 
               title: item.Title, 
               id: item.Id,
               location: item.Location
                  };
        });

        //push to a more usable array 
        for(var i=0;i<nameArray.length;i++){
          productsGlobal.push(nameArray[i]);
          //alert('I am ritems of item ' + nameArray[1].id);

       }
        alert('I am productsglobal of item ' + productsGlobal[1].title);

    }, (error: any): void => {

        alert('Loading all items failed with error' + error);

    });

    var selectRowProp = {
      mode: "checkbox",
      clickToSelect: true,
      bgColor: "rgb(238, 193, 213)" 
    };


    // The gray background
    const backdropStyle = {
      position: 'fixed',
      top: 0,
      bottom: 0,
      left: 0,
      right: 0,
      backgroundColor: 'rgba(0,0,0,0.3)',
      padding: 50
    };

    // The modal "window"
    const modalStyle = {
      backgroundColor: '#fff',
      borderRadius: 5,
      maxWidth: 500,
      minHeight: 300,
      margin: '0 auto',
      padding: 30
    };

    return (
      <div className="container">
          <div>
               <h6>Location Search</h6>
               <input type='text' width='20' id='meta-area' placeholder="Start typing..."/>
                 <input id='meta_search_ids' value='' />
                 <br /><br />

                 <div className={styles.vicinfo} ><br />
                 <strong>You selected the following location:</strong><br />
                 <form>
                    ID:<span> <input id="id"  value='' /></span>
                     <br />
                      Title: <span><input id="label"  value=''  /></span>
                     <br />
                      Address:<span> <input id="address"  value=''/> </span>
                      </form>
                 </div>


          <br /><br /><br />
        <p>{escape(this.props.description)}</p>
              <div href='https://github.com/SharePoint/sp-dev-docs/wiki' >
            Learn more
              </div>
              <input  id="btnShowSecondComp" type="submit" value="View Locations Directory"/>

              <div>  


              <BootstrapTable
                      data={productsGlobal}
                      selectRow={selectRowProp}
                      striped
                      hover
                      condensed
                      pagination
                      insertRow
                      deleteRow
                      search>
                  <TableHeaderColumn dataField="id" isKey={true} dataAlign="right" dataSort width="5%">Course ID</TableHeaderColumn>
                  <TableHeaderColumn dataField="title" dataSort width="5%">Title</TableHeaderColumn>
                  <TableHeaderColumn dataField="location" dataAlign="center" width="5%">Location</TableHeaderColumn>
                </BootstrapTable>


              </div>
          </div>
          Component 3
          <PanelB count={10} 
          key={null} onChange=""
          index={null} id={null} onRemove details="" description={this.props.description} text="" title="" category={this.props.category} image={this.props.image}> 
           Hello World
           </PanelB>
          <div>


              </div>
    </div>  

    );

  }
}
KidKode
  • 179
  • 3
  • 11
  • My guess would be to use https://reactjs.org/docs/react-component.html#shouldcomponentupdate and check wether something has changed – SuperDJ Jan 25 '18 at 12:02
  • Thanks so if my data is loaded in componentDidMount and I set the state in this, then in shouldcomponentupdate I set it to False, how would I code this to say 'don't change state and remove as well don't add empty rows' if the state is the same i.e. no new data from API? – KidKode Jan 25 '18 at 12:25
  • What I do is check states so `this.state !== nextState` based on that return true or false. If that doesn't cut it check a more specific state. After this should update you can also use `componentdidupdate` in wich you can setstate if required – SuperDJ Jan 25 '18 at 12:36
  • Perfect...Will be trying this before close of play. Thanks. – KidKode Jan 25 '18 at 14:12

1 Answers1

0

DO NOT make http calls in render method ! You can do that in c̶o̶m̶p̶o̶n̶e̶n̶t̶W̶i̶l̶l̶M̶o̶u̶n̶t̶ componentDidMount for example and set the return values in the state. When you update the state, react will call the render method and redraw your component.

jb cazaux
  • 322
  • 1
  • 8
  • Thanks, I am not making HTTP calls in render anymore, now it's in the componentDidMount and I am updating my state too in same method. – KidKode Jan 25 '18 at 12:21