Categories
React Tips

React Tips — Get Data, Check Scrolling, and Way Use React Router Properly

Spread the love

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

‘You should not use Route or withRouter() outside a Router when using react-router 4’ Error with the styled-components Library

To fix this error, we should make sure that we wrap the BrowserRouter component around our app.

For instance, we can write:

import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
   <BrowserRouter>
     <App />
   </BrowserRouter>
, document.getElementById('root'));

Listening to Window Events from Components

We can listen to events by attach event listeners in the componentDidMount method.

Then the listener is added when the component mounts.

We can remove the listen with removeEventListener in the componentWillUnmount to clean it up.

For instance, we can write:

class Home extends Component {
  constructor(props) {
    super(props)
    this.handleScroll = this.handleScroll.bind(this);
  }

  componentDidMount() {
    window.addEventListener('scroll', this.handleScroll);
  }

  componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScroll);
  }

  handleScroll(e) {
    console.log('scrolled');
    console.log(e);
  }

  render() {
    return (
     <div>
       <Foo />
       <Bar />
       <Baz />
     </div>
    );
  }
}

We added the scroll event listener in compoonentDidMount .

The handler is the this.handleScroll method.

Then we have the removeEventListener method call within componentWillUnmount .

“Using string literals in ref attributes is deprecated (react/no-string-refs)” Lint Warning

We shouldn’t be using string refs since they’re being deprecated.

Instead, we can use createRef or callback refs.

For instance, we can write:

class App extends Component {
  constructor() {
    super();
    this.btnRef = React.createRef();
    this.handleClick = this.handleClick.bind(this);
  }

  render() {
    return (
      <div>
        <button ref={this.btnRef} onClick={this.handleClick}>click me</button>
      </div>
    );
  }
}

The ref is created with createRef .

We assigned the ref to the button with the ref prop.

Also, we can assign a ref with a callback as follows:

class App extends Component {
  constructor() {
    super();
    this.btnRef;
    this.state = { clicked: false };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(){
    //...
  }

  render() {
    return (
      <div>
        <button ref={(el) => this.btnRef = el} onClick={this.handleClick}>click me</button>
      </div>
    );
  }
}

We get the element with the el parameter and then set it to this.btnRef .

Set State of Response from Axios in React

We can set the state inside the callback.

For instance, we can write:

axios.get('/url')
 .then((response) => {
   this.setState({ events: response.data })
 })
.catch(function (error) {
   console.log(error);
});

We make a GET request to a URL, then call setState on it.

We’ve to use an arrow function so that we can access the correct this , which is the component itself.

A full example would be the following:

import React from 'react';
import axios from 'axios';
export default class App extends React.Component {
  state = {
    persons: []
  }

  componentDidMount() {
    axios.get(`https://jsonplaceholder.typicode.com/users`)
      .then(({ data }) => {
        const persons = data;
        this.setState({ persons });
      })
  }

  render() {
    return (
      <div>
        { this.state.persons.map(person => <p>{person.name}</p>)}
      </div>
    )
  }
}

We make the same request and get the data from the data property of the response,

Then we call setState to update the persons state.

In the render method, we render the persons state array into paragraphs.

Detecting When User Scrolls to Bottom of div with React

We can listen for scroll events.

In the scroll event handler, we can get the getBoundClientRect method’s bottom property and compare it to the window.innerHeight to see of the div is at the bottom of the div.

For instance, we can write:

class App extends Component {
  constructor(props) {
    super(props);
    this.headerRef = React.createRef();
  }

  isBottom(el) {
    return el.getBoundingClientRect().bottom <= window.innerHeight;
  }

  componentDidMount() {
    document.addEventListener('scroll', this.trackScrolling);
  }

  componentWillUnmount() {
    document.removeEventListener('scroll', this.trackScrolling);
  }

  trackScrolling(){
    if (this.isBottom(headerRef)) {
      document.removeEventListener('scroll', this.trackScrolling);
    }
  };

  render() {
    return (
      <div ref={this.headerRef}>
        ...
      </div>
    }
  }
}

We create the ref with the createRef in the constructor,.

Then in componentDidMount , we listen to the scroll event.

We added the trackScrolling method to listen to the scroll event.

Then we check is we scrolled to the bottom of the div with getBoundingClientRect ‘s returned object to check if we scrolled to the bottom of the div.

Conclusion

There are various ways to check for scrolling.

Also, we shouldn’t use string refs.

And can get data from Axios and set the state to render the data.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *