Ishan Patel
Ishan Patel

Reputation: 6091

How to update react state without re-rendering component?

I am building a gallery app where I need to create multiple HTTP requests to pull gallery entries(images & videos).

As gallery will be auto scrolling entries, I am trying to prevent re-rendering component when I make subsequent HTTP requests and update the state.

Thanks

Upvotes: 35

Views: 84220

Answers (6)

cr4z
cr4z

Reputation: 581

None of the answers work for TypeScript, so I'll add this. One method is to instead use the useRef hook and edit the value directly by accessing the 'current' property. See here:

const [myState, setMyState] = useState<string>("");

becomes

let myState = useRef<string>("");

and you can access it via:

myState.current = "foobar";

Do note however that if this is to prevent a child component from updating, look into using the useMemo hook instead.

Upvotes: 19

AFC
AFC

Reputation: 11

If you just need a container to store the values, try useRef. Changing the value of ref.current doesn't lead to re-rendering.

Upvotes: 1

Mahesh M
Mahesh M

Reputation: 21

const [ loading,setLoading] = useState(false)

loading=true //does not rerender
setLoading(true) //will rerender

In functional component refer above code, for class use componentShouldUpdate lifecycle

Upvotes: 0

Uku Lele
Uku Lele

Reputation: 594

All data types

useState returns a pair - an array with two elements. The first element is the current value and the second is a function that allows us to update it. If we update the current value, then no rendering is called. If we use a function, then the rendering is called.

const stateVariable = React.useState("value");

stateVariable[0]="newValue"; //update without rendering
stateVariable[1]("newValue");//update with rendering

Object

If a state variable is declared as an object, then we can change its first element. In this case, rendering is not called.

const [myVariable, setMyVariable] = React.useState({ key1: "value" });

myVariable.key1 = "newValue"; //update without rendering
setMyVariable({ key1:"newValue"}); //update with rendering

Array

If a state variable is declared as an array, then we can change its first element. In this case, rendering is not called.

const [myVariable, setMyVariable] = React.useState(["value"]);

myVariable[0] = "newValue"; //update without rendering
setMyVariable(["newValue"]); //update with rendering

Upvotes: 25

Ike Anya
Ike Anya

Reputation: 201

It's as easy as using this.state.stateName = value. This will change the state without re-rendering, unlike using this.setState({stateName:value}), which will re-render. For example;

class Button extends React.Component {
    constructor( props ){
        super(props);
        this.state = {
            message:"Hello World!"
        };
        this.method = this.method.bind(this);
    }
    method(e){
        e.preventDefault();
        this.state.message = "This message would be stored but not rendered";
    }
    render() {
        return (
            <div >
                {this.state.message}
                <form onSubmit={this.method}> 
                    <button type="submit">change state</button>
                </form>
            </div>
        )
    }
}
ReactDOM.render(<Button />, document.getElementById('myDiv'));

Upvotes: 3

Colin Ricardo
Colin Ricardo

Reputation: 17249

Here's an example of only re-rendering when a particular condition is fulfilled (e.g. finished fetching).

For example, here we only re-render if the value reaches 3.

import React, { Component } from 'react';
import { render } from 'react-dom';

class App extends React.Component { 
  state = { 
    value: 0, 
  }

  add = () => {
    this.setState({ value: this.state.value + 1});
  } 

  shouldComponentUpdate(nextProps, nextState) { 
    if (nextState.value !== 3) { 
      return false;
    }
    return true;
  }

  render() { 
    return (
      <React.Fragment>
        <p>Value is: {this.state.value}</p>
        <button onClick={this.add}>add</button>
      </React.Fragment>
    )
  }
}

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

Live example here.

Upvotes: 29

Related Questions