react props español enhancer component reactjs react-router

reactjs - props - Diferencia de enrutador de reacción entre componente y render



react router (3)

Así que estoy confundido en esta sección de documentos también, pero finalmente lo descubro.

La clave para entender esto es la declaración " proporcionar una función en línea al componente prop "

Todos sabemos que el componente de Ruta se volverá a generar cuando la ubicación cambie, y reaccionará comparará el árbol DOM virtual anterior y el nuevo, obtendrá un resultado diferente y se aplicará al DOM real.

Y reaccionará e intentará reutilizar el nodo DOM, a menos que se cambie el tipo o la clave del nuevo ReactElement.

Asi que

// 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

Todos los ReactElements creados por la vía 1 tienen el mismo tipo (componente de la aplicación), pero no tienen el mismo tipo si se crean por la vía 2.

¿Por qué?

Debido a que siempre se crea una nueva función anónima en la forma 2 cuando se invoca el método de procesamiento del componente principal (el componente que contiene el componente de Ruta), el tipo de ReactElement nuevo y antiguo son dos instancias diferentes de la función anónima

() => <App />

Por lo tanto, en el punto de vista de React, hay diferentes tipos de elementos y se deben tratar con desmontar> montar una nueva operación, lo que significa que cada estado o cambio que haya hecho en el componente anterior se perdió cada vez que el componente principal se vuelve a representar.

Pero, ¿por qué el soporte de representación evita el comportamiento de desmontaje y montaje? ¿Es una función anónima también?

Aquí me gustaría referir el código que @Rishat Muhametshin publicó, la parte central del método de renderizado del componente Route:

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 es una función que devuelve un ReactElement cuando se invoca, ¿cuál es el tipo de ese elemento devuelto?

<Route render={() => <AppComponent />}></Route>

Es AppComponent, no el envoltorio de la función anónima! Porque después de jsx compilado:

render = () => React.createElement(AppComponent) render() = React.createElement(AppComponent) React.createElement(render) = React.createElement(() => React.createElement(AppComponent)) React.createElement(render()) = React.createElement(React.createElement(AppComponent))

Por lo tanto, cuando utiliza la representación en lugar de la propiedad de componente, el tipo de elemento que devuelve la función de la propuesta no cambiará en cada presentación, incluso siempre se creará una nueva instancia de función anónima en cada parentElement.render ()

Desde mi punto de vista, puede archivar el mismo comportamiento que la representación de prop con el componente prop al asignar un nombre a la función anónima:

// Put this line outside render method. const CreateAppComponent = () => <AppComponent /> // Inside render method render(){ return <Route component={CreateAppComponent}/> }

Entonces, la conclusión es que no hay un rendimiento diferente entre el componente y la prop de renderización si utiliza use component = {AppComponent} directamente, si desea asignar algunos props a AppComponent, use render={() => <AppComponent {...props}/> } lugar de component={() => <AppComponent {...props}/> }

Realmente no entiendo la diferencia entre el render y el componente en Route en el enrutador de reacción, en los documentos dice que el render no crea un nuevo elemento, pero el componente sí. Intenté volver con el historial, pero encontré que se llama a componentWillMount cuando use render en Route, ¿qué quiere decir con "si proporciona una función en línea para el atributo de componente, crearía un nuevo componente en cada render. Esto da como resultado el desmontaje del componente existente y el montaje del nuevo componente en lugar de solo actualizar el componente existente? . "


La mayoría de los conceptos se han explicado mediante otras respuestas. Permítanme resolverlo siguiendo:

En primer lugar, tenemos el código fuente :

if (component) return match ? React.createElement(component, props) : null if (render) return match ? render(props) : null

caso # 1: componente sin función

<Route path="/create" component={CreatePage} />

React.createElement(CreatePage, props) debido a React.createElement(component, props) del código fuente. La instanciación causaría que se vuelva a montar .

caso # 2: render sin función

<Route path="/create" render={CreatePage} />

React.createElement(CreatePage, props) antes de pasar a render prop, y luego se llamó por render(props) desde el código fuente. Sin instanciación, sin remontar.

caso # 3: componente con función

<Route path="/create" component={ () => <CreatePage /> } />

React.createElement(CreatePage, props) se llamará dos veces . Primero para el análisis jsx (función anónima), segundo desde el código fuente. Entonces, ¿por qué no hacer esto en prop componente?

caso # 4: render con función

<Route path="/create" render={ () => <CreatePage /> } />

Hay una instanciación (análisis jsx) cada vez que se enruta a path=/create . ¿Se siente como el caso # 1 ?

Conclusión

De acuerdo con los cuatro casos, si queremos pasar prop a Component, necesitamos usar el caso # 4 para evitar que se vuelva a montar.

<Route path="/abc" render={()=><TestWidget num="2" someProp={100}/>}/>

Esto está un poco lejos del tema, así que abandono la discusión oficial para leer más.


El código fuente dice la diferencia:

if (component) return match ? React.createElement(component, props) : null if (render) return match ? render(props) : null

Cuando utiliza el component prop, el componente se crea una instancia para cada llamada de Route#render de Route#render . Significa que, para su componente que pase al component prop de Route, constructor, componentWillMount y componentDidMount se ejecutarán cada vez que se renderice la ruta.

Por ejemplo, si tiene

<Route path="/:locale/store" component={Store} />

y el usuario navega a / en / store, luego va a otro lugar, y luego navega de regreso a / en / store, el componente Store se montará, luego se desmontará y luego se volverá a montar. Es similar a hacer

<Route path="/:locale/store"> <Store /> </Route>

Comparado con eso, si usa la prop de render , el componente se evalúa en cada representación de Route#render . ¿Recuerdas que cada componente es una función? Esta función se ejecutará tal cual, sin ningún método de ciclo de vida. Así que cuando lo tengas como

<Route path="/:locale/store" render={Store} />

puedes considerarlo como

<Route path="/:locale/store"> {Store()} </Route>

Le ahorra tiempo de ejecución porque no se ejecutan métodos de ciclo de vida, pero también tiene un inconveniente en caso de que el componente Store tenga algunos métodos de ciclo de vida posteriores al montaje, como shouldComponentUpdate, que también pueden aumentar el rendimiento.

Hubo una buena publicación en Medium sobre este truco de rendimiento , por favor, eche un vistazo. Está escrito muy bien y es aplicable a React 16, también.