setState는 React의 중요한 부분으로 구성 요소 상태에 대한 변경 사항을 대기열에 추가하고 업데이트된 상태로 이 구성 요소와 하위 구성 요소를 다시 렌더링해야 함을 React에 알립니다. 다음 기사는 React의 setState 메커니즘을 이해하는 데 도움이 될 것입니다.
state
는 React
에서 중요한 개념입니다. 우리는 React
가 상태 관리를 통해 구성 요소를 관리한다는 것을 알고 있습니다. 그렇다면 React
는 구성 요소의 상태를 어떻게 제어하며, 구성 요소를 관리하기 위해 상태를 어떻게 사용합니까? [관련 권장 사항: Redis 동영상 튜토리얼]state
是React
中的重要概念。我们知道,React
是通过状态管理来实现对组件的管理。那么,React
是如何控制组件的状态的,又是如何利用状态来管理组件的呢?【相关推荐:Redis视频教程】
我们都知道,React
通过this.state
来访问state
,通过this.setState()
方法更新state
。当this.setState()
被调用的时候,React
会重新调用render
方法来重新渲染UI
。
setState
已经是我们非常熟悉的一个API
,然而你真的了解它吗?下面我们将一起来解密setState
的更新机制。
setState异步更新
大家刚开始写React
的时候,通常会写出 this.state.value = 1
这样的代码,这是完全错误的写法。
注意:绝对不要直接修改 this.state,这不仅是一种低效的做法,而且很有可能会被之后的操作替换。
setState
通过一个队列机制实现state
更新。当执行setState
时,会将需要更新的state
合并后放入状态对列,而不会立刻更新this.state
,队列机制可以高效地批量更新state
。如果不通过setState
而直接修改this.state
的值,那么该state
将不会被放入状态队列中,当下次调用setState
并对状态队列进行合并时,将会忽略之前直接被修改的 state
,而造成无法预知的错误。
因此,应该使用 setState
方法来更新 state
,同时 React
也正是利用状态队列机制实现了 setState
的异步更新,避免频繁地重复更新 state
。相关代码如下:
// 将新的state合并到状态更新队列中 var nextState = this._processPendingState(nextProps, nextContext); // 根据更新队列和 shouldComponentUpdate 的状态来判断是否需要更新组件 var shouldUpdate = this._pendingForceUpdte || !inst.shouldCompoonentUpdate || inst.shouldComponentUpdate(nextProps, nextState, nextContext0;
setState循环调用风险
当调用setState
时,实际上会执行 enqueueSetState
方法,并对 partialState
以及 _pendingStateQueue
更新队列进行合并操作,最终操作 enqueueSetState
执行 state
更新。
而 performUpdateIfNecessary
方法会获取 _pendingElement、_pendingStateQueue、_pendingForceUpdate
,并调用 receiveComponent
和 updateComponent
方法进行组件更新。
如果在 shouldComponetUpdate
或 componentWillUpdate
方法中调用 setState
, 此时 this._pendingStateQueue != null
, 则 performUpateIfNecessary
方法就会调用 updateComponent
方法进行组件更新,但 updateComponent
方法又会调用 shouldComponentUpdate
和 componentWillUpdate
方法,因此造成循环调用,使得浏览器内存占满后崩溃。
setState调用栈
既然 setState
最终是通过 enqueueUpate
执行 state
更新,那么 enqueueUpdate
到底是如何更新 state
的呢?
首先,看看下面这个问题,你是否能够正确回答呢?
import React, { Component } from 'react' class Example extends Component { constructor() { super() this.state = { val: 0 } } componentDidMount() { this.setState({val: this.state.val + 1}) console.log(this.state.val) this.setState({val: this.state.val + 1}) console.log(this.state.val) setTimeout(() => { this.setState({val: this.state.val + 1}) console.log(this.state.val) this.setState({val: this.state.val + 1}) console.log(this.state.val) },0) } render() { return null } }
上述代码中, 4 次 console.log
打印出来的 val
分别是:0、0、2、3
。
假如结果与你心中的答案不完全相同,那么你是否想知道 enqueueUpdate
setState
调用栈,注意其中核心的状态判断。
setState
简化调用栈
解密setState
到底是怎么导致 setState
우리 모두 알고 있습니다, React
는 this.state
를 통해 state
에 액세스하고 this.setState()
메서드를 통해 state
를 업데이트합니다. . this.setState()
가 호출되면 React
는 UI
를 다시 렌더링하기 위해 render
메서드를 다시 호출합니다. .
setState
는 이미 우리에게 매우 익숙한 API
인데, 정말 이해하고 계시나요? 아래에서는 setState
의 업데이트 메커니즘을 해독합니다. 🎜setState 비동기 업데이트
🎜모든 사람이 처음React
작성을 시작할 때 일반적으로 this.state.value = 1 을 작성합니다. code> 그런 코드는 완전히 잘못된 코드입니다. 🎜<blockquote>🎜참고: 절대로 this.state를 직접 수정하지 마세요. 이는 비효율적인 접근 방식일 뿐만 아니라 후속 작업으로 대체될 가능성도 있습니다. 🎜</blockquote>🎜<code>setState
는 대기열 메커니즘을 통해 상태
업데이트를 구현합니다. setState
가 실행되면 업데이트가 필요한 state
가 병합되어 상태 큐에 들어가고 this.state
는 업데이트되지 않습니다. 즉시 업데이트됩니다. 메커니즘은 상태
를 일괄적으로 효율적으로 업데이트할 수 있습니다. setState
없이 this.state
의 값을 직접 수정하면 다음에 호출할 때 state
가 상태 대기열에 추가되지 않습니다. setState
를 사용하여 상태 대기열을 병합하면 이전에 직접 수정된 상태
가 무시되어 예측할 수 없는 오류가 발생합니다. 🎜🎜따라서 state
를 업데이트하려면 setState
메서드를 사용해야 합니다. 동시에 React
는 상태 대기열 메커니즘을 사용하여 setState 코드의 비동기 업데이트>는 상태
의 빈번한 반복 업데이트를 방지합니다. 해당 코드는 다음과 같습니다. 🎜import ReactDOM, { unstable_batchedUpates } from 'teact-dom' unstable_batchedUpates(() => { this.setState(val: this.state.val + 1) this.setState(val: this.state.val + 1) })
setState 루프 호출 위험
🎜setState
호출 시 enqueueSetState
실제로 실행됩니다. > 메서드를 실행하고 partialState
및 _pendingStateQueue
업데이트 대기열에서 병합 작업을 수행하고, 마지막 작업 enqueueSetState
는 >상태
업데이트. 🎜🎜 performUpdateIfNecessary
메서드는 _pendingElement, _pendingStateQueue, _pendingForceUpdate
를 획득하고 receiveComponent
및 updateComponent
메서드를 호출하여 업데이트합니다. 구성 요소. 🎜🎜setState
가 shouldComponetUpdate
또는 comComponentWillUpdate
메서드에서 호출되면 this._pendingStateQueue != null
입니다. performUpateIfNecessary
메소드는 updateComponent
메소드를 호출하여 구성요소를 업데이트하지만 updateComponent
메소드는 shouldComponentUpdate
를 호출하고 componentWillUpdate 메서드로 인해 루프 호출이 발생하여 메모리가 가득 찬 후 브라우저가 중단됩니다. 🎜🎜
setState 호출 스택
🎜setState
는 궁극적으로 enqueueUpate
를 통해 상태
업데이트를 수행하므로 어떻게 해야 할까요? enqueueUpdate
가 상태
를 업데이트하나요? 🎜🎜우선, 다음 질문을 잘 보세요. 정답을 맞힐 수 있나요? 🎜rrreee🎜위 코드에서 console.log
에 의해 4번 출력된 val
은 0, 0, 2, 3
입니다. 🎜🎜결과가 마음속에 있는 대답과 정확하게 일치하지 않으면 enqueueUpdate
가 실제로 무엇을 하는지 알고 싶으십니까?
아래 그림은 단순화된 setState
호출 스택입니다. 핵심 상태 판단에 주의하세요. 🎜🎜
setState 암호 해독
🎜어떻게setState
의 다양한 성능으로 이어지나요? 🎜我们先要了解事务跟 setState
的不同表现有什么关系。首先,我们把4次 setState
简单归类,前两次属于一类,因为他们在同一次调用栈中执行,setTimeout
中的两次 setState
属于另一类,因为他们也是在同一次调用栈中执行。我们分析一下这两类 setState
的调用栈。
在 componentDidMount
中直接调用的两次 setState
,其调用栈更加复杂;而setTimeout
中调用的两次 setState
,其调用栈则简单很多。下面我们重点看看第一类 setState
的调用栈,我们发现了 batchedUpdates
方法,原来早在 setState
调用前,已经处于batchedUpdates
执行的事务中了。
那batchedUpdates
方法,又是谁调用的呢?我们再往前追溯一层,原来是 ReactMount.js 中的 _renderNewRootComponent
方法。也就是说,整个将React组件渲染到DOM中的过程就处于一个大的事务中。
接下来的解释就顺理成章了,因为在componentDidMount
中调用setState
时,batchingStrategy
的 isBatchingUpdates
已经被设为true
,所以两次setState
的结果并没有立即生效,而是被放到了dirtyComponents
中。这也解释了两次打印 this.state.val
都是 0
的原因,因为新的 state
还没有被应用到组件中。
componentDidMount
中setState
的调用栈
setTimeout
中setState
的调用栈
再反观 setTimeout
中的两次setState
,因为没有前置的 batchedUpdate
调用,所以 batchingStrategy
的 isBatchingUpates
标志位是false
,也就导致了新的 state
马上生效,没有走到 dirtyComponents
分支。也就是说,setTimeout
中第一次执行 setState
时,this.state.val
为 1
, 而 setState
完成打印后打印时 this.state.val
变成了2
。第二次的 setState
同理。
前面介绍事务时,也提到了其在 React
源码中的多处应用,像 initialize、perform、close、closeAll、motifyAll
等方法出现在调用栈中,都说明当前处于一个事务中。
既然事务这么有用,我们写应用代码时能使用它吗?很可惜,答案是不能。尽管React
不建议我们直接使用事务,但在 React 15.0
之前的版本中还是为开发者提供了 batchedUpdates
方法,它可以解决针对一开始例子中setTimeout
里的两次 setState
导致两次 render
的情况:
import ReactDOM, { unstable_batchedUpates } from 'teact-dom' unstable_batchedUpates(() => { this.setState(val: this.state.val + 1) this.setState(val: this.state.val + 1) })
在 React 15.0
以及之后版本中,已经彻底将 batchUpdates
这个 API
移除了,因此不再建议开发者使用它。
总结
在使用React
的setState
的过程中,了解setState
的实现原理,对setState
异步更新、setState
循环调用风险、setState
调用栈等进行更加全面的了解,才能让我们在遇到相关问题的时候更加游刃有余。
更多编程相关知识,请访问:编程入门!!
위 내용은 React의 setState 업데이트 메커니즘에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

javaandjavaScriptAredistIntLanguages : javaisusedforenterpriseandmobileApps, whilejavaScriptisforInciveWebPages.1) javaiscompiled, 정적으로 정적, Andrunsonjvm.2) javaScriptISNaterPreted, doineslicallytyted, andrunsinbrowsorsornode.js.3) javausepith

JavaScript 코어 데이터 유형은 브라우저 및 Node.js에서 일관되지만 추가 유형과 다르게 처리됩니다. 1) 글로벌 객체는 브라우저의 창이고 node.js의 글로벌입니다. 2) 이진 데이터를 처리하는 데 사용되는 Node.js의 고유 버퍼 객체. 3) 성능 및 시간 처리에는 차이가 있으며 환경에 따라 코드를 조정해야합니다.

javaScriptUSTWOTYPESOFSOFCOMMENTS : 단일 라인 (//) 및 multi-line (//)

Python과 JavaScript의 주요 차이점은 유형 시스템 및 응용 프로그램 시나리오입니다. 1. Python은 과학 컴퓨팅 및 데이터 분석에 적합한 동적 유형을 사용합니다. 2. JavaScript는 약한 유형을 채택하며 프론트 엔드 및 풀 스택 개발에 널리 사용됩니다. 두 사람은 비동기 프로그래밍 및 성능 최적화에서 고유 한 장점을 가지고 있으며 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

Python 또는 JavaScript를 선택할지 여부는 프로젝트 유형에 따라 다릅니다. 1) 데이터 과학 및 자동화 작업을 위해 Python을 선택하십시오. 2) 프론트 엔드 및 풀 스택 개발을 위해 JavaScript를 선택하십시오. Python은 데이터 처리 및 자동화 분야에서 강력한 라이브러리에 선호되는 반면 JavaScript는 웹 상호 작용 및 전체 스택 개발의 장점에 없어서는 안될 필수입니다.

파이썬과 자바 스크립트는 각각 고유 한 장점이 있으며 선택은 프로젝트 요구와 개인 선호도에 따라 다릅니다. 1. Python은 간결한 구문으로 데이터 과학 및 백엔드 개발에 적합하지만 실행 속도가 느립니다. 2. JavaScript는 프론트 엔드 개발의 모든 곳에 있으며 강력한 비동기 프로그래밍 기능을 가지고 있습니다. node.js는 풀 스택 개발에 적합하지만 구문은 복잡하고 오류가 발생할 수 있습니다.

javaScriptisNotBuiltoncorc; it'SangretedLanguageThatrunsonOngineStenWrittenInc .1) javaScriptWasDesignEdasAlightweight, 해석 hanguageforwebbrowsers.2) Endinesevolvedfromsimpleplemporectreterstoccilpilers, 전기적으로 개선된다.

JavaScript는 프론트 엔드 및 백엔드 개발에 사용할 수 있습니다. 프론트 엔드는 DOM 작업을 통해 사용자 경험을 향상시키고 백엔드는 Node.js를 통해 서버 작업을 처리합니다. 1. 프론트 엔드 예 : 웹 페이지 텍스트의 내용을 변경하십시오. 2. 백엔드 예제 : node.js 서버를 만듭니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는