简体   繁体   English

在不触发重新渲染的情况下调用 setState

[英]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.我将 UI state 存储在 React 组件的state中,比如this.state.receivedElements是一个数组。 I want re-renders whenever an element is pushed to receivedElements .每当将元素推送到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?或者一般来说,我可以只调用setState()一次而不重新渲染,而在所有其他时间都重新渲染吗? ( are there any options, work-arounds? ) (有什么选择,解决方法吗?)
I've read through this thread: https://github.com/facebook/react/issues/8598 but didn't find anything.我已经阅读了这个线程: https://github.com/facebook/react/issues/8598但没有找到任何东西。

I want re-renders whenever an element is pushed to receivedElements . 我想重新呈现每当一个元素被推向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. 是的-在这种情况下不调用setState

It sounds as though receivedElements shouldn't be part of your state, but instead information you manage separately and reflect in state as appropriate. 听起来好像receivedElements不应成为您状态的一部分,而是您可以单独管理信息并在state适当反映 For instance, you might have receivedElements on the component itself, and displayedElements on state . 例如,您可能已经在组件本身上receivedElements了Element,在state displayedElementsstate 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. 请注意,如果this.receivedElements为空,我们如何不调用setState

What about useRef ? useRef呢?

Documentation says: useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue).文档说: useRef返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数 (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.因此,如果您更改 useEffect 中的 ref 值,它将不会重新渲染组件。

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

useState returns a pair - an array with two elements. useState 返回一个pair - 一个包含两个元素的数组。 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 关联

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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