简体   繁体   中英

Calling setState without triggering re-render

I am storing a UI state in the React component's state , say this.state.receivedElements which is an array. I want re-renders whenever an element is pushed to receivedElements . My question is, can I not trigger rendering when the array becomes empty?
Or in general, can I call setState() just one time without re-render while re-rendering all other times? ( are there any options, work-arounds? )
I've read through this thread: https://github.com/facebook/react/issues/8598 but didn't find anything.

I want re-renders whenever an element is pushed to receivedElements .

Note that you won't get a re-render if you use:

this.state.receivedElements.push(newElement); // WRONG

That violates the restriction that you must not directly modify state. You'd need:

this.setState(function(state) {
    return {receivedElements: state.receivedElements.concat([newElement])};
});

(It needs to be the callback version because it relies on the current state to set the new state.)

My question is, can I not trigger rendering when the array becomes empty ?

Yes — by not calling setState in that case.

It sounds as though receivedElements shouldn't be part of your state, but instead information you manage separately and reflect in state as appropriate. For instance, you might have receivedElements on the component itself, and displayedElements on state . Then:

this.receivedElements.push(newElement);
this.setState({displayedElements: this.receivedElements.slice()});

...and

// (...some operation that removes from `receivedElements`...), then:
if (this.receivedElements.length) {
    this.setState({displayedElements: this.receivedElements.slice()});
}

Note how we don't call setState if this.receivedElements is empty.

What about useRef ?

Documentation says: useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.

So if you change ref value inside useEffect it won't rerender component.

  const someValue = useRef(0)
  useEffect(() => {
    someValue.current++
  },[])

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

link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM