분류 Reactjs

React 동시 모드를 활성화하는 방법

컨텐츠 정보

  • 조회 386 (작성일 )

본문

동시 모드는 사용자 경험과 개발자 경험을 크게 향상 시킵니다. 활성화하는 방법은 다음과 같습니다.


https://kentcdodds.com/blog/how-to-enable-react-concurrent-mode 


React의 새로운 동시 모드실험 릴리스 채널에 게시되었습니다. 수년간의 연구 결과와 그 결과입니다. 왜 그것이 멋진 지에 대해 더 배우고 싶다면 Dan Abramov의 JSIceland 이야기를 확실히 보십시오. 그리고 사람들은 그것을 가지고 놀기 시작했고 멋진 퍼프가 상자에서 승리하는 것을 보았습니다.


이 모든 것이 실험적이라는 것을 기억하십시오. 실험용 릴리스 채널은 semver를 존중하지 않으므로 (코드에 의존하는 코드가 예기치 않게 중단 될 수 있음) 버그가 있을 수 있습니다. 그러나 초기 실험은 많은 사람들에게 유망했으며 귀하의 앱에서 시도해 볼 것을 제안합니다.


1 단계 


설치 


먼저, 동시 모드를 사용하려면 이를 지원하는 React 버전이 있어야 합니다. 이 글을 쓰는 시점에서 React 및 React DOM은 동시 모드를 지원하지 않는 버전 16.11.0입니다. 실험 버전을 설치해야 합니다.


npm install react@experimental react-dom@experimental
# or: yarn add react@experimental react-dom@experimental


2 단계 


다른 것을 변경하지 않고 앱이 작동하는지 확인하십시오. 


앱을 실행하고 빌드를 실행하며 테스트 / 유형 검사를 실행하십시오. 콘솔에 이전에 없었던 새로운 오류가 있는 경우 React의 버그 일 수 있으며 최소한의 재생산을 시도하고 (바람직 하게는 코드 샌드 박스에서) React 저장소에서 새로운 문제를 열어야 합니다.


종종 이 단계를 건너 뛰지만 문제가 있는 경우 이러한 문제가 시작된 단계를 알고 있는지 확인하는 것이 중요합니다. 일반적으로 좋은 조언 ?


3 단계 


동시 모드를 활성화합니다. 


프로젝트의 입력 파일에 다음과 같은 것이 있을 것입니다.


import React from 'react'
import ReactDOM from 'react-dom'
import App from './app'
const rootEl = document.getElementById('root')
ReactDOM.render(<App />, rootEl)

동시 모드를 활성화하려면 새로운 createRoot API를 사용합니다.


import React from 'react'
import ReactDOM from 'react-dom'
import App from './app'
const rootEl = document.getElementById('root')
// ReactDOM.render(<App />, rootEl)
const root = ReactDOM.createRoot(rootEl)
root.render(<App />)


4 단계 


다른 것을 변경하지 않고 앱이 작동하는지 확인하십시오. 


앱을 실행하고 빌드를 실행하며 테스트 / 유형 검사를 실행하십시오. 콘솔에 이전에 없었던 새로운 오류가 있는 경우 React의 버그 일 수 있으며 최소한의 재생산을 시도하고 (바람직 하게는 코드 샌드 박스에서) React 저장소에서 새로운 문제를 열어야 합니다.


익숙한 것처럼 보이면 2 단계에서 복사하여 붙여 넣었기 때문입니다.


그러나 이 경우에 문제가 발생하거나 콘솔에 새 오류가 있는 경우입니다. 앱에 동시 모드에서 지원되지 않는 기능 (예 : 문자열 참조, 레거시 컨텍스트 또는 findDOMNode)을 사용하는 코드가 있기 때문일 수 있습니다.


또한 unsafe_ 접두사가 있는 모든 라이프 사이클 메소드는 실제로 안전하지 않으므로 이 메소드를 사용하면 버그가 발생합니다.


5 단계 


동시 모드를 사용해보십시오. Concurrent Mode가 가능하게 하는 두 가지 주요 사항이 있습니다.

  1. 타임 슬라이싱
  2. 비동기식으로 모든 것에 대한 긴장

앱에서 약간의 사용자 상호 작용이 느리다는 것을 알고 있다면 그것을 시도하고 덜 고요하다면 직장에서 시간을 내십시오 (Dan의 대화가 위에 링크되어 있음을 참조하십시오).


비동기 상호 작용 중 하나를 리팩토링 하여 긴장을 풀거나 앱의 어딘가에 추가하십시오.


const TRANSITION_CONFIG = {
2 timeoutMs: 3000, // ? Play with this number a bit...
3}
4function SuspenseDemo() {
5 const [greetingResource, setGreetingResource] = React.useState(null)
6 const [startTransition, isPending] = React.useTransition(TRANSITION_CONFIG)
7
8 function handleSubmit(event) {
9 event.preventDefault()
10 const name = event.target.elements.nameInput.value
11 startTransition(() => {
12 setGreetingResource(createGreetingResource(name))
13 })
14 }
15
16 return (
17 <div>
18 <strong>Suspense Demo</strong>
19 <form onSubmit={handleSubmit}>
20 <label htmlFor="nameInput">Name</label>
21 <input id="nameInput" />
22 <button type="submit">Submit</button>
23 </form>
24 <ErrorBoundary>
25 <React.Suspense fallback={<p>loading greeting</p>}>
26 <Greeting greetingResource={greetingResource} isPending={isPending} />
27 </React.Suspense>
28 </ErrorBoundary>
29 </div>
30 )
31}
32
33function Greeting({greetingResource, isPending}) {
34 return (
35 <p style={{opacity: isPending ? 0.4 : 1}}>
36 {greetingResource ? greetingResource.read() : 'Please submit a name'}
37 </p>
38 )
39}
40
41// ? make this function do something else. Like an HTTP request or something
42function getGreeting(name) {
43 return new Promise((resolve, reject) => {
44 setTimeout(() => {
45 resolve(`Hello ${name}!`)
46 // ? try rejecting instead... (make sure to comment out the resolve call)
47 // reject(new Error(`Oh no. Could not load greeting for ${name}`))
48 }, 1500) // ? play with this number a bit
49 })
50}
51
52// ? This should NOT be copy/pasted for production code and is only here
53// for experimentation purposes. The API for suspense (currently throwing a
54// promise) is likely to change before suspense is officially released.
55function createGreetingResource(name) {
56 let status = 'pending'
57 let result
58 let suspender = getGreeting(name).then(
59 greeting => {
60 status = 'success'
61 result = greeting
62 },
63 error => {
64 status = 'error'
65 result = error
66 },
67 )
68 return {
69 read() {
70 if (status === 'pending') throw suspender
71 if (status === 'error') throw result
72 if (status === 'success') return result
73 },
74 }
75}
76
77class ErrorBoundary extends React.Component {
78 state = {error: null}
79 static getDerivedStateFromError(error) {
80 return {error}
81 }
82 componentDidCatch() {
83 // log the error to the server
84 }
85 tryAgain = () => this.setState({error: null})
86 render() {
87 return this.state.error ? (
88 <div>
89 There was an error. <button onClick={this.tryAgain}>try again</button>
90 <pre style={{whiteSpace: 'normal'}}>{this.state.error.message}</pre>
91 </div>
92 ) : (
93 this.props.children
94 )
95 }
96}

대신 codesandbox에서 이것을 사용하십시오.


내가 찾은 것 중 하나는 서스펜스 API가 상당히 저수준이므로 잘 작동 시키기 위해 많은 코드가 필요하다는 것입니다. 그러나 멋진 점은 이것들이 추상화 내에서 잘 작동하고 쉽게 공유 할 수 있는 원자 적 특징이라는 것입니다. 일단 추상화를 하면 황금색입니다. 그것은 굉장.


6 단계 


모든 변경 사항을 취소하십시오. 


이전에 설치 한 마지막 안정 버전을 다시 설치하고 이전의 ReactDOM.render를 복원하십시오. 동시 모드는 실험적이며 문제가 없는 것처럼 보일지라도 실험 소프트웨어를 기본적으로 React와 같은 방식으로 제공하는 것은 좋지 않습니다. React 문서는 앱의 크기와 사용 중인 타사 라이브러리에 따라 동시 모드를 제공하지 못할 수도 있다고 제안합니다 (Facebook은 현재 이전 Facebook.com에서 동시 모드를 활성화 할 계획이 없습니다).


또한 커뮤니티로서 우리는 이러한 것들을 가지고 놀기 시작 했으므로 다른 접근법에 대한 트레이드 오프와 관련하여 여전히 많은 미지의 사람들이 있습니다. 신나는 시간입니다. 그러나 안정성을 중요하게 생각하면 동시 모드와 서스펜스가 잠시 존재하지 않는 것처럼 보일 수 있습니다.


7 단계 


엄격한 모드를 사용하십시오. 


엄격 모드를 통과하지 않은 앱은 동시 모드에서 제대로 작동하지 않을 수 있습니다. 따라서 앱에서 동시 모드를 사용하려면 엄격한 모드를 사용하십시오. 엄격 모드의 좋은 점 중 하나는 (동시 모드와 달리) 점진적으로 채택 할 수 있다는 것입니다. 따라서 엄격하게 알고 있는 코드베이스의 일부에만 엄격 모드를 적용한 다음 시간이 지남에 따라 전체 지원을 반복 할 수 있습니다.


내 블로그에서 이에 대해 자세히 알아보십시오. 엄격한 모드 사용 방법.


결론 


데이터 가져 오기를 위해 Concurrent Mode 및 Suspense의 안정적인 릴리스를 기대하고 있습니다. 프레임 워크와 라이브러리가 이러한 새로운 기능을 활용할 때 훨씬 더 시원해질 것입니다. React Hooks가 React 생태계에 대한 것 만큼이나 훌륭하기 때문에 동시 모드는 개발자 경험과 최종 사용자 모두에게 더 영향을 줄 것이라고 생각합니다.