React Tips — Infinite Scroll, Submit, Focus, and Drag and Drop
Tags: react, webdev, programming, javascript
Published: 2021-01-21 21:44:58

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


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.

### onSubmit in React

To run a submit handler in a React app, we should call `preventDefault` to prevent the default submit behavior, which is to submit to a server.

For instance, we write:

```
class App extends React.Component {

  submit(e){
    e.preventDefault();
    alert('submitted');
  }

  render() {
    return (
      <form onSubmit={this.submit}>
        <button type='submit'>click me</button>
      </form>
    );
  }
});
```

We called `e.preventDefault()` with the `submit` method, which we pass as the value of the `onSubmit` prop.

### React onClick Being Called on Render

We’ve to pass in the reference to a function instead of calling it.

For instance, we write:

```
class Create extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    const playlist = this.renderPlaylists(this.props.playlists);
    return (
      <div>
        {playlist}
      </div>
    )
  }

  renderPlaylists(playlists) {
    const activatePlaylist = this.activatePlaylist.bind(this, playlist.id);
    return playlists.map(playlist => {
      return (
        <div key={playlist.id} onClick{activatePlaylist}>
          {playlist.name}
        </div>
      );
    })
}
```

We have:

```
this.activatePlaylist.bind(this, playlist.id)
```

which returns a function that changes the value of `this` to the current component.

Also, it passes the `playlist.id` as the argument to the `this.activatePlaylist` method.

### Making React Component or Element Draggable

To create a draggable component easily, listen to the `mousemove`, `mousedown`, and `mouseup` events

For instance, we can write:

```
import React, { useRef, useState, useEffect } from 'react'

const styles = {
  width: "200px",
  height: "200px",
  background: "green",
  display: "flex",
  justifyContent: "center",
  alignItems: "center"
}

const DraggableComponent = () => {
  const [pressed, setPressed] = useState(false)
  const [position, setPosition] = useState({x: 0, y: 0})
  const ref = useRef()

  useEffect(() => {
    if (ref.current) {
      ref.current.style.transform = `translate(${position.x}px, ${position.y}px)`
    }
  }, [position])

  const onMouseMove = (event) => {
    if (pressed) {
      setPosition({
        x: position.x + event.movementX,
        y: position.y + event.movementY
      })
    }
  }

  return (
    <div
      ref={ref}
      style={styles}
      onMouseMove={ onMouseMove }
      onMouseDown={() => setPressed(true)}
      onMouseUp={() => setPressed(false)}>
      <p>drag me</p>
    </div>
  )
}
```

We have the `Draggable` component with some props.

We listen to the `mousedown` and `mouseup` events to set the `pressed` state to be `false` and `true` respectively.

This will let us dragged if the `pressed` state is `true` , which is when we’re dragging.

Then we add a listener for the `mousemove` event by passing the `onMouseMove` function to the `onMouseMove` prop.

Then we set the position in the `onMouseMove` function.

We set the position by changing the `x` and `y` coordinates of the div if `pressed` is `true` .

### Infinite Scrolling with React

To add infinite scrolling easily with React, we can use the react-infinite-scroller package.

To install it, we run:

```
npm install react-infinite-scroller
```

Then we can use it by writing:

```
import React, { Component } from 'react';
import InfiniteScroll from 'react-infinite-scroller';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      listData: [],
      hasMoreItems: true,
      nextHref: null
    };
    this.fetchData = this.fetchData.bind(this);
  }

  async fetchData(){
    const listData  = await getJobsData();
    this.setState({ listData });
  }

  componentDidMount() {
     this.fetchData();
  }

  render() {
    const loader = <div className="loader">Loading ...</div>;
    const JobItems = this.state.listData.map(job => {
      return (<div>{job.name}</div>);
    });
    return (
      <div className="Jobs">
         <h2>Jobs List</h2>
         <InfiniteScroll
           pageStart={0}
           loadMore={this.fetchData.bind(this)}
           hasMore={this.state.hasMoreItems}
           loader={loader}
         >
            {JobItems}
         </InfiniteScroll>
      </div>
    );
  }
}
```

We use the `InfiniteScroll` component to add infinite scrolling to our app.

`pageStart` is the starting page number.

`loadMore` is the function to load more data.

`hasMore` is the state to see if we have more data.

`loader` is the loader component.

We get new data every time we load and scroll to the bottom of the page.

### Select All Text in Input with React When it’s Focused

We can call the `select` method on the input to focus it.

For instance, we can write:

```
const Input = (props) => {
  const handleFocus = (event) => event.target.select();

  return <input type="text" value="something" onFocus={handleFocus} />
}
```

We have the `handleFocus` function that calls the `select` method on the input element to select the input value when it’s focused.

With a class component, we can write:

```
class Input extends React.Component {
  constructor(){
    super();
    this.handleFocus = this.handleFocus.bind(this);
  }

  handleFocus(event){
    event.target.select();
  }

  render() {
    return (
      <input type="text" value="something" onFocus={this.handleFocus} />
        );
    }
}
```

We have the `handleFocus` method to call `select` to select the input value when we focus the input.

### Conclusion

We can use a package to add infinite scrolling easily.

Also, we can select the values of the input.

We can add a draggable item to our component without a library.

We’ve to call `preventDefault` to stop the default submit behavior.