How can I render my react component smoothly?

How can I render my react component smoothly?
0.0 0

#1

Hi, I’m trying to learn React and decided to create an web application.

I have an array of javascript objects as my application state. This array of objects contain information about stores. This is rendered and the user can see the stores with their corresponding data. The user can also search for a place, that search will trigger an api request to google distance matrix that will find the distance between the origin (user search) and all of the stores. The array (application state) will then be updated with a distance for each store, triggering a re render so the user can see the the information again, but now updated with distance and transportation duration.

It currently works if the user submits twice, if you submit once, nothing happens, even though you can see in console that the request has been made and the state has been updated (containing distance and duration). If you submit once again, it re renders. Do you have any ideas? I tried to put set state inside the result callback, that worked, but it was very laggy because set state was called a lot.

App.js

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      stores: stores,
    }
    this.addressSearch = this.addressSearch.bind(this);
  }

  addressSearch(address){
    console.log('firing search for distance. Origin is: ' + address)
    let origin = [address];
    let service = new google.maps.DistanceMatrixService();
    stores.map(store => service.getDistanceMatrix({
    origins: origin,
    destinations: store.addressapi,
    travelMode: 'DRIVING'
    }, result => {
    store.distance = result.rows["0"].elements["0"].distance.text;
    store.duration = result.rows["0"].elements["0"].duration.text;
    }))
    this.setState({stores})
  }
  
  render() {
    return (
      <MuiThemeProvider>
        <div className='App'>
          <SearchBar onSearchTermChange={this.addressSearch}/>
          <WarehouseList stores={this.state.stores}/>
          <Footer />
        </div>
      </MuiThemeProvider>
    );
  }
}

export default App;

Searchbar.js

class SearchBar extends Component {
  constructor(props) {
    super(props)
    this.state = {
      address: '',
      loading: false
    }
    this.handleSelect = this.handleSelect.bind(this)
    this.handleChange = this.handleChange.bind(this)
  }

  handleSelect(address) {
    this.setState({
      address: address,
      loading: true
    })
    this.props.onSearchTermChange(address);
  }

  handleChange(address) {
    this.setState({
      address,
    })
  }

  render() {
    const styles = {
	    justifyContent: 'space-around',
    }
    const cssClasses = {
      root: 'form-group',
      input: 'Demo__search-input',
      autocompleteContainer: 'Demo__autocomplete-container',
    }

    const AutocompleteItem = ({ formattedSuggestion }) => (
      <div className="Demo__suggestion-item">
        <i className='fa fa-map-marker Demo__suggestion-icon'/>
        <strong>{formattedSuggestion.mainText}</strong>{' '}
        <small className="text-muted">{formattedSuggestion.secondaryText}</small>
      </div>)

    const inputProps = {
      type: "text",
      value: this.state.address,
      onChange: this.handleChange,
      onBlur: () => { console.log('Blur event!'); },
      onFocus: () => { console.log('Focused!'); },
      autoFocus: true,
      placeholder: "Sök efter plats",
      name: 'Demo__input',
      id: "my-input-id",
    }

    const options = {
      types: ['address'],
      componentRestrictions: {
        country: ['se'] 
      }
    }

    return (
      <AppBar>
        <Toolbar style={styles} className="toolbar">
          <Typography type="title" colorInherit><a href="/">Hitta närmsta NoN lagershop</a></Typography>
            <div className='container'>
              <PlacesAutocomplete
                options={options}
                onSelect={this.handleSelect}
                autocompleteItem={AutocompleteItem}
                onEnterKeyDown={this.handleSelect}
                classNames={cssClasses}
                inputProps={inputProps}
              />
            </div>
        </Toolbar>
      </AppBar>
    )
  }
}

export default SearchBar;

#2

So… I’m not keen on debugging this app, but I can give a couple of tips. One, pick up a browser extension for React debugging. I’m not sure which browser you typically prefer, but I think Chrome has the best debug extensions for React at this time. Two, you’ll definitely want to use Redux, or any other state management library, as this will significantly cut down on the surface area for bugs. I suggest Redux as it’s popular and easy to use, so you’ll get lots of help if you need it, and it lays the foundation for learning other state management libraries. Check out LearnCode.Academy’s videos, they’re great:

I created a simple Redux project that you can reference as well. It doesn’t use React, but it does show you how to make AJAX calls with Redux (which I had a hard time finding good examples of at the time).