컴포넌트와 렌더 간의 리액트라우터 차이
Route in react 라우터의 Route와 컴포넌트 프로포트의 차이를 잘 모르겠습니다.docs에서는 렌더가 새로운 요소를 생성하지 않는다고 합니다만, component Will Mount는 이력으로 되돌아가려고 했지만 Route에서 렌더를 사용하면 component Will Mount가 호출됩니다."컴포넌트 속성에 인라인 함수를 제공하면 렌더링할 때마다 새 컴포넌트가 생성됩니다.따라서 기존 컴포넌트를 업데이트만 하는 것이 아니라 기존 컴포넌트를 마운트 해제하고 새 컴포넌트를 마운트할 수 있습니다."
소스 코드는 다음과 같은 차이를 나타냅니다.
if (component)
return match ? React.createElement(component, props) : null
if (render)
return match ? render(props) : null
「 」를 사용하는 component 됩니다.Route#render즉, 이 컴포넌트에 대해component, 컨스트럭터, 컨스트럭터, 컨스트럭터, 컨스트럭터,componentWillMount , , , , 입니다.componentDidMount는 루트가 렌더링될 때마다 실행됩니다.
예를 들어,
<Route path="/:locale/store" component={Store} />
사용자는 /en/store로 이동하고 다른 곳으로 이동한 후 /en/store로 돌아갑니다. Store 구성 요소가 마운트되었다가 마운트 해제되었다가 다시 마운트됩니다.하는 것과 비슷하다
<Route path="/:locale/store">
<Store />
</Route>
에해해를 render프로펠러, 컴포넌트는 모든 컴포넌트에서 평가됩니다.Route#render모든 컴포넌트가 기능이라는 것을 기억하십니까?이 기능은 라이프 사이클 방식 없이 그대로 실행됩니다.그래서 그걸 가지고 있을 때
<Route path="/:locale/store" render={Store} />
라고 생각하시면 됩니다
<Route path="/:locale/store">
{Store()}
</Route>
실행 중인 수명 주기 방법이 없기 때문에 실행 시간을 절약할 수 있지만 Store 구성 요소에 성능을 향상시킬 수 있는 wakeComponentUpdate와 같은 마운트 후 수명 주기 방법이 있는 경우에도 단점이 있습니다.
이 퍼포먼스 해킹에 대해 Medium에 좋은 글이 올라왔는데 한번 봐주세요.매우 잘 쓰여져 있어 React 16에도 적용할 수 있습니다.
그래서 저도 문서의 이 부분에 대해 혼란스럽지만, 마침내 알아냈습니다.
이를 이해하는 열쇠는 "컴포넌트 프로펠러에 인라인 함수를 제공한다"는 문구입니다.
장소가 변경되면 루트 컴포넌트가 재렌더되고 리액션이 오래된 가상 DOM 트리와 새로운 가상 DOM 트리를 비교하여 다른 결과를 얻어 실제 DOM에 적용됩니다.
또한 새로운 ReactElement의 유형이나 주요 요소를 변경하지 않는 한 DOM 노드를 재사용하는 것이 가장 좋습니다.
그렇게
// 1.
const componentA = React.createElement(App, props)
const componentB = React.createElement(App, props)
console.log(componentA.type === componentB.type) // true
// 2.
const componentA = React.createElement(() => <App />, props)
const componentB = React.createElement(() => <App />, props)
console.log(componentA.type === componentB.type) // false
방법 1로 작성된 모든 React Elements는 유형(App 구성 요소)이 동일하지만 모두 방법 2로 작성된 경우에는 유형이 동일하지 않습니다.
왜요?
부모 컴포넌트(Route 컴포넌트를 포함하는 컴포넌트) 렌더 메서드를 호출했을 때 2의 방법으로 작성된 새로운 어나니머스 함수가 항상 존재하기 때문에 new 및 old ReactElement의 유형은 어나니머스 함수의 두 가지 다른 인스턴스가 됩니다.
() => <App />
따라서 React의 관점에서는 다양한 유형의 요소가 존재하며 old > mount new 조작으로 처리해야 합니다.즉, 부모 컴포넌트가 재렌더될 때마다 오래된 컴포넌트에서 수행한 모든 상태 또는 변경이 손실됩니다.
그러나 렌더 프로포트가 마운트 해제 및 마운트 동작을 피하는 이유는 무엇입니까?그것도 익명의 행사야!?
여기에서는 Route 컴포넌트 렌더링 메서드의 핵심 부분인 @Rishat Muhametshin이 게시한 코드를 참조합니다.
if (component)
// We already know the differences:
// React.createElement(component)
// React.createElement(() => <component/>)
return match ? React.createElement(component, props) : null
if (render)
return match ? render(props) : null
render prop은 호출 시 ReactElement를 반환하는 함수입니다. 반환된 요소의 유형은 무엇입니까?
<Route render={() => <AppComponent />}></Route>
앱 컴포넌트이지 익명 함수 래퍼가 아닙니다!jsx 컴파일 후:
render = () => React.createElement(AppComponent)
render() = React.createElement(AppComponent)
React.createElement(render) =
React.createElement(() => React.createElement(AppComponent))
React.createElement(render()) =
React.createElement(React.createElement(AppComponent))
따라서 컴포넌트 프로펠러 대신 렌더링을 사용하면 각 렌더에서 프로펠러 함수를 반환하는 요소의 유형은 변경되지 않습니다.각 parentElement.render()에는 항상 새로운 익명 함수 인스턴스가 생성됩니다.
제 관점에서는 익명의 함수에 이름을 붙이면 렌더 프로펠이 컴포넌트 프로펠러와 같은 동작을 할 수 있습니다.
// Put this line outside render method.
const CreateAppComponent = () => <AppComponent />
// Inside render method
render(){
return <Route component={CreateAppComponent}/>
}
으로 컴포넌트=직접 컴포넌트와 차이는 AppComponentAppComponent}를 AppComponent에 AppComponent를 합니다.render={() => <AppComponent {...props}/> }component={() => <AppComponent {...props}/> }
대부분의 개념은 다른 답변으로 설명되어 있습니다.다음으로 정리하겠습니다.
if (component)
return match ? React.createElement(component, props) : null
if (render)
return match ? render(props) : null
케이스 #1: 기능이 없는 컴포넌트
<Route path="/create" component={CreatePage} />
React.createElement(CreatePage, props)을 받다React.createElement(component, props)소스 코드로부터.인스턴스화로 인해 다시 마운트됩니다.
케이스 #2: 기능을 사용하지 않는 렌더링
<Route path="/create" render={CreatePage} />
React.createElement(CreatePage, props) 렌더 소품으로 전달하기 전에 호출된 다음 에 의해 호출되었습니다.render(props)스스코코코코코코인스턴스화도 재마운트도 없습니다.
케이스 3: 기능이 있는 컴포넌트
<Route path="/create" component={ () => <CreatePage /> } />
React.createElement(CreatePage, props)두 번 호출되다첫 번째는 jsx 구문 분석(익명 함수)이고, 첫 번째는 의 인스턴스를 반환하는 것입니다.CreatePage소스 코드에서 두 번째, 익명 기능에서 두 번째입니다.컴포넌트 프로펠러에서 이 작업을 수행하는 것은 어떨까요?
오류는 oligofren에 의해 지적됩니다.
JSX를 해석해도 호출되지 않습니다.결국 함수식을 생성하게 됩니다.3번을 하지 않는 이유는 매번 새로운 어나니머스 타입을 생성하여 돔을 다시 마운트하기 때문입니다.
케이스 #4: 렌더링(기능 포함)
<Route path="/create" render={ () => <CreatePage /> } />
다음에 라우팅 할 때 매번 인스턴스화(jsx 구문 분석)가 발생합니다.path=/create1번 케이스처럼 느껴지나요?
결론
4가지 케이스에 따르면 컴포넌트에 프로펠러를 넘기는 경우 케이스 #4를 사용하여 재마운트를 방지해야 합니다.
<Route path="/abc" render={()=><TestWidget num="2" someProp={100}/>}/>
이것은 주제와 조금 동떨어져 있기 때문에, 저는 공식적인 논의를 남겨두고 더 읽어 보도록 하겠습니다.
소품을 넘겨주지 않더라도ComponentToRender컴포넌트 대신 렌더링을 사용함으로써 얻을 수 있는 이점이 있습니다.디폴트<Route \>추가 소품을 전달하다{ history, location, match })에 대해서ComponentToRender컴포넌트 사용 시.이 소품에는 렌더 콜백을 통해서도 액세스 할 수 있습니다만, 생략할 수도 있습니다.그게 왜 필요하죠?모든 렌더링<Route />'s부모 또는 임의의 내비게이션(경로를 이전과 동일하게 변경하더라도)이 새로 생성됩니다.match물건.그래서 우리가 그걸 전달해 줄 때ComponentToRender매번 새로운 소품을 구입합니다.특히 퍼포먼스 문제를 일으킬 수 있는 것은PureComponent.
함수에 이름을 붙여도 부모 컴포넌트에서 이 컴포넌트가 호출될 때 새로운 참조가 생성됩니다.그 새로운 참조는 컴포넌트에 전달됩니다.그러나 콜백 후크를 사용하면 새로운 참조가 생성되는 것을 방지할 수 있습니다.
// Put this line outside render method.
const CreateAppComponent = () => <AppComponent />
// Inside render method
render(){
return <Route component={CreateAppComponent}/>
}
언급URL : https://stackoverflow.com/questions/48150567/react-router-difference-between-component-and-render
'programing' 카테고리의 다른 글
| JSON의 용량에 제한이 있습니까? (0) | 2023.03.28 |
|---|---|
| angular: 여러 종속 필드 검증 (0) | 2023.03.28 |
| Jasmine 테스트에서 Angular가 표시되지 않음JS 모듈 (0) | 2023.03.28 |
| 워드프레스 미리보기_post_link (0) | 2023.03.28 |
| 요소 또는 요소는 프런트 엔드 뷰에서 작성된 콘텐츠의 데이터를 어디에 저장합니까? (0) | 2023.03.28 |