No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Qué son las render props y render functions

8/19
Recursos

Aportes 21

Preguntas 6

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Antes de estudiar las render props debes conocer la composición de componentes. Las renders props vienen a ayudar a hacer una composición de componentes más limpia. Seguimos con todas las ventajas de usar composición de componentes.
A partir de ahora podemos decir que tenemos 2 tipos de props: las props normales que reciben un valor o variable y por otro lado tenemos las props que contienen una función. Estas que contienen una función son las que nos interesan.
Esta función devuelve un componente o un elemento que pudiera tener anidados más elementos y componentes.
La sintaxis es la siguiente:

<MyHeader 
	render={ () => <myLogo type={ type } /> } 
/> 

La propiedad render(la cual puede tener cualquier otro nombre) es nuestra render prop, porque contiene una función que al ser llamada devuelve un componente. Entonces cumple todas las condiciones y solo falta llamarla desde el componente que la contiene:

function MyHeader( props ){
	return (
	<header className="header__styles">
		{ props.render() }
	</header>
	)
} 

Entonces podemos interpretar que las render props le dicen al componentes que renderizan(cual va a ser su contenido)

Otra forma de hacer esto es con las render functions y lo que cambia es que se declaran dentro del componente:

<MyHeader>
	{ () => <myLogo type={ type } /> } 
</MyHeader>

Y para acceder a lo que está dentro del componentes simplemente usamos props.children:

function MyHeader( props ){
	return (
	<header className="header__styles">
		{ props.children }
	</header>
	)
} 

Es prácticamente lo que hicimos con la composición de componentes y la propiedad children.
¡Usen render props y mejoren sus composiciones amigos 😃 !

8.-Qué son las render props y render functions


Nos ayudan a elevar nuestra composición de componentes a otro nivel.


Las render props nos permiten ser más específicos sobre que vamos a renderizar, cuando y donde vamos a renderizar cada parte del contenido de nuestros componentes.


Render Function


Es el patrón de entregar la información de nuestro componente en una función. No es exclusivo de react context, nosotros podemos crear nuestros propios componentes que usen este patrón, que reciban una función para que le podamos enviar la información que queremos proveer y luego si, renderizar los componentes que ya tienen la info gracias a la función.


Render Props


Cuando ya no mandamos la función dentro del componente, si no que la enviamos en alguna otra propiedad del componente. Podemos jugar con este patrón para que compartir información sea más divertido.

Voy a repasar esto muy bien para entenderlo.

Render Props

Documentación oficial:
https://es.reactjs.org/docs/render-props.html

Hola Juan, las clases donde solo hablas y enseñas imágenes con ejemplos son un coñazo🤦‍♂️, mola mucho más cuando escribes el código y explicas al mismo tiempo con los ejemplos se entiende mucho mejor 👍.

no se si soy el unico pero, casi no le entiendo a juan, me toca estar mirando videos en youtube para alimentar lo que dice

🌦️ Render Props y Render Functions

Ideas/conceptos claves

Render Function El patrón de entregar la información en una función es lo que llamamos

Render Prop El patrón de enviar como propiedad una función

Apuntes

  • Son un patrón que nos ayudan a llevar la composición de componentes a un mayor nivel
  • Render Props nos dejan especificar:
    • Que vamos a renderizar
    • Cuando lo vamos a renderizar
    • Donde lo vamos a renderizar
<Provider>
	<Consumer>
		{ something => (
				<TusComponentes
					{...something.xyz}
				/>
		)}
	</Consumer>
</Provider>
  • React context se puede utilizar a través de los componentes de Provider y Consumer
    • Con el componente consumer podíamos recibir una función con todas las propiedades que habíamos guardado en el provider, el concepto de esta aplicación es **Render Function**
  • También podemos realizar el siguiente código la cual utiliza Render Props
<RenderProps
	renderProp={<OtroCompo />}
/>

<RenderProps
	renderProp={info => <OtroCompo {...info} />}
/>

Por ejemplo podríamos realizar la siguiente aplicación

<PlatziCourse
	classes={platziClass => (
		<PlatziClassPreview {...platziClass} />
	)}
	lastActivity={question => (
		<PlatziComment q={true} {...question} />
	)}
/>

Qué son las render props y render functions

.
Los componentes provider y consumer: por dentro del componente consumer podemos recibir una función con todas las propiedades que habíamos guardado en el provider y que queríamos compartir en toda la aplicación ese patron de entregar la información de nuestro componente en una función, es lo que nosotros llamamos una render function.

<Provider value={...something}>
	<Consumer>
		{something => (
			<TusComponentes
				{...something.xyz}
			>	
		)}
	</Consumer>
</Provider>

.

Render props:

Cuando la función ya no la enviamos dentro del componente en su propiedad { children } sino que la enviamos en alguna otra propiedad del componente, puede ser cualquiera, se puede jugar mucho con ese patron para que compartir información y hacer composición de componentes sea mas divertido.

<RenderProps
  renderProp={<OtroCompo />}
/>

<RenderProps
  renderProp={info => <OtroCompo {...info} />}
/>

Ejemplo:

<PlatziCourse
  classes={platziClass => (
    <PlatziClassPreview {...platziClass} />
  )}

  lastActivity={question => (
    <PlatziComment q={true} {...question} />
  )}
/>

una render prop es una prop que recibe una función que un componente utiliza para saber qué renderizar.

<PlatziClasses
	latestClasses = {(studentClasses) => (
		<LastClassContainer>
			{
				studentClasses.map((scItem) => (
					<LastClassItem {...scItem} />
				))
			}
		</LastClassContainer>
	)}
	rutasEscuelas = {
		(studentRutasEscuelas) => (
			<>
				{
				studentRutasEscuelas.map((rsItem) => (
						<RutaEscuelaItem {...rsItem} />
					))
				}
			</>
		)
	}	
/>

Opino que con las render props se lee mucho mejor el código (con tal de que se manejen buenos nombres de las props).

wtf class my head exploded too many slices that do not specify what it does I get lost between what it explains and the slice that shows this class should separate it into two classes
en términos sencillos desde mi punto de vista puedo indicar lo siguiente: * ver un componente como una variable, siendo mas precisos como una función, lo que realmente así lo es. * ver estos como pasajeros de primera clase; es decir que gozan de todos los beneficios y artificios q se pueden hacer con las funciones. * los componentes al ser funciones, podemos hacer uso de los clousures pero en este caso clousers de componentes. * ahora un componente goza de props que estos pueden ser enviados como propiedades o "parametros" o en su cuerpo como {children} como si fuera un simple "return" * pero estas props pueden ser componentes, por lo que estamos pasando componentes en componentes, en fin solo mirar como si fueran funciones y deja volar tu creatividad..

Esto es excelente! Muchas gracias… Adicionalmente, revisando la documentación render props oficial hay un ejemplo donde es siguiente código es equivalente… 🤯

<Mouse children={mouse => (
  <p>The mouse position is {mouse.x}, {mouse.y}</p>
)}/>

<Mouse>
  {mouse => (
    <p>The mouse position is {mouse.x}, {mouse.y}</p>
  )}
</Mouse>

Supongo que React hace su magia detrás del telón con JSX para convertir todo esto en el código que entrega al navegador…

En cada render prop, cuando estemos devolviendo esa nueva función, tenemos que definir un componente especifico para esa parte de la maquetación y de esta manera evitar usar React Context. Simplemente recibimos esa función e inyectamos las propiedades al componente

⠀⠀⠀⡇⡇⠀ ⠀⠀⡇ ⠀⠀⠀⡆⡇⠀ ⠀⠀⡇⡄ ⠀⠀⠀⠁⡇⠇⠀⡂⡇⡇ ⠀⠀⠀⡇⣇⠃⠀⣇⣁⡇ ⠀⠀⠀⣧⣿⣷ ⣾⣿⡷ ⠀⠀⠀⠘⣿⣿ ⣿⡏ ⠀⠀⠀⠀⢸⣿ ⣿⡇⠀⣀ ⠀⠀⠀⠀⣸⣿ ⣿⡷⠛⣿ ⠀⢀⠀⠀⣿⣿⡿⣷⣶⣿⣤⡴⠞⢿ ⠀⢸⠀⠀⣿⣿⣿⠰⢹⡿⢿⣿⣤⠟ ⠀⠘⢸⠀⣿⣿⣿⣏⣽⣄⣃⣿⡇ ⠀⢸⢨⢠⣼⣿⣿⣿⣿⣿⣿⡟ ⠀⠘⣠⡌⢿⣿⣿⣿⣿⣿⣄⠀ ⠀⢸⣿⡿⢸⣿⣿⣿⣿⣿⣿⣧ ⠀⠀⣿⡇⠀⣿⣿⣿⣿⣿⣿⣿⣧ ⠀⠀⣿⣧⣶⣿⣿⣿⣿⣿⣿⣿⣿ ⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏ ⠀⠀⠀⠻⠿⠟⠛⠻⠿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠈⣿⡄ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣄⠀⠀⠀⢀⣿⠇ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⢷⣶⣶⠿⠋ Esta es mi propuesta de solución a los temas visto en la clase vs la respuesta sugerida por el profesor. Mi código tiene sus errores, pero hasta de los errores se aprende: ```js <> <> <PlatziComponente clasesVistas={ () => <ClasesVistas/> } rutasAprendizaje={ () => <ClasesVistas/> } > </PlatziComponente> {/* Otra porpuesta */} <PlatziHome lastClasses={classPreview => ( <ClassPreview {...classPreview} /> )} learningPaths={lp => ( <LearningPathView {...lp} /> )} /> <> <form envioExitoso={ () => <GreenEnvioExitoso/> } envioFallido={ error => <RedEnvioFallido error={error}/> } > <input></input> <label></label> <button> </button> </form> {/* Otra porpuesta */} <SuperFormMessage envioExitoso={ newData => <GreenEnvioExitoso data={newData}/> } envioFallido={ error => <RedEnvioFallido error={error}/> } > </SuperFormMessage> ```
.

Qué son las render props y render functions

.
Las render props y las render functions son un patrón que nos ayuda a elevar nuestra composición de componentes.
.
Las render props siguen la misma línea que la composición de componentes, pero son más específicas acerca de:
.

  • Qué se va a renderizar
  • Cuándo se va a renderizar
  • Dónde se va renderizar cada parte del contenido de nuestros componentes.

.

Render functions

.

<Provider value={...something}>
	<Consumer>
		{something => (
			<TusComponentes
				{...something.xyz} 
			/>
		)}
	</Consumer>
</Provider>

.
Al utilizar React Context vimos que en los componentes Provider y Consumer, por dentro el componente Consumer podía recibir una función con todas las propiedades que habíamos guardado en nuestro provider y que quería compartir en toda la aplicación.
.
A este patrón de entregar la información de nuestro componente en una función, se le denomina Render Function.
.
Por ejemplo, imaginemos que tenemos una aplicación donde se necesita pasar la información de un usuario al componente UserProfile. Lo que se hace es guardar en la propiedad value el objeto user o en este caso también puede usarse el operador de spread operator para hacer un copia superficial del mismo con { ...user }.
.

function App() {
  const user = {
    id: 1,
    name: "John Doe",
    email: "[email protected]",
    role: "admin",
  };

  return (
    <UserContext.Provider value={{ ...user }}>
      <Module title="Render Functions">
        <UserProfile />
      </Module>
    </UserContext.Provider>
  );
}

.
Luego desde UserProfile consumimos la información mediante el Consumer y utilizando una render function que recibe la información del objeto user como parámetro y empieza a maquetar el componente.
.

function UserProfile() {
  return (
    <UserContext.Consumer>
      {(user) => (
        <div className="user-card">
          <h2>{user.name}</h2>
          <p>Email: {user.email}</p>
          <p>Role: {user.role}</p>
        </div>
      )}
    </UserContext.Consumer>
  );
}

.
No es algo exclusivo de React Context por lo que podemos crear nuestros propios componentes que utilicen este patrón.
.

<RenderFucntion>
		{info => (
			<OtroComponente {...info} />
		)}
</RenderFucntion>

.
Estas reciben una función, a través de la cual enviamos la información que queremos proveer y luego renderizamos el componente.
.

Render props

.
La función ya no la enviamos dentro del componente en su propiedad children, sino que lo enviamos en alguna propiedad del componente.
.

<Course 
	classes={class => (
		<ClassPreview {...class} />
	)}

	lastActivity={question => (
		<Comment q={true} {...question} />
	)}
/>

.
Podríamos tener un componente Course donde su propiedad Classes recibe una función con todo un listado de clases que se puede utilizar para renderizar un preview de cada clase. Incluso se puede combinar con otro render prop lastActivity donde recibimos las últimas preguntas del curso y mostramos un preview de esa pregunta para poder ir a responderla.
.

<Class 
	video={videoUrl => (
		<VideoPlayer src={videoUrl} />
	)}

	comment={comment => (
		<Comment {...comment} />
	)}
/>

.
Otro ejemplo, un componente Class donde en su propiedad video tenemos una render prop con la url del video de cada clase. También tenemos una propiedad comment que nos permite ver una lista de comentario e iterar cada una para hacer un preview de las preguntas de la clase.
.
Lo que se va a hacer es trasformar el componente TodoList para que ya no simplemente renderice todo lo que tenga en children.
.

<TodoList>
	{error&&<TodosError/>}
	{loading&&<TodosLoading/>}
	{(!loading&&!searchedTodos.length)&&<EmptyTodos/>}
	{searchedTodos.map(todo=>(
		<TodoItem
			key={todo.text}
			text={todo.text}
			completed={todo.completed}
			onComplete={()=>completeTodo(todo.text)}
			onDelete={()=>deleteTodo(todo.text)}/>
	))}
</TodoList>

.
Debemos lograr obtener entonces una render prop por cada distinto estado que puedan tener los TODOs y dentro de estas propiedades recibamos una función que retornándola nos permita renderizar nuestros componentes según los distintos estados:
.

  • TODOs cargando → renderizamos mediante la render prop onLoading.
  • Error → onError.
  • Todos los TODOs cargado pero no hay ninguno → onEmptyTodos.
  • TODOs cargados y sí hay alguno → render.

.

<TodoList
	onError={error => <TodosError error={error} />}
	onLoading={() => <TodosLoading />}
	onEmptyTodos={()=> <EmptyTodos />}
	render={todo => <TodoItem {...todo} />}
/>

.
Otros ejemplos son los siguientes.
.
Tenemos un componente Home con 2 render props:
.

  • La primera, lastClasses envía toda la información de las últimas clases que vio cada estudiante para poder renderizar un preview.
  • La segunda, learningPaths nos da la información de todas las rutas de aprendizaje de cada estudiante y luego poder mostrar un preview de esa ruta.

.
Por dentro cada render prop tiene que recibir una función para poder enviar la información requerida.
.
En cada render prop al estar devolviendo esa nueva función debemos definir un componente muy específico para esa parte de la maquetación.
.
Evitamos el uso de React Context y simplemente recibimos la función y le inyectamos esas propiedades a nuestro componente.
.

<Home
	lastClasses={classesPreview => (
		<ClassPreview {...classPreview} />
	)}
	learningPaths={lp => (
		<LearningPathPreview {...lp} />
	)}
/>

.
Otro ejemplo, sería tener un formulario SuperFormMessage con 2 render props.
.
Este componente por dentro se encarga de mostrar lo que hay en onError u en onSuccess, incluso ninguno de los dos dependiendo de cómo estén llenando los usuarios el formulario.
.

<SuperFormMessage
	onError={error => (
		<FormError error={error} />
	)}
	onSuccess={newData => (
		<FormSuccess data={newData} />
	)}
/>

Render props

Permiten elevar la composición de componentes a otro nivel.

Similar a component composition pero permiten ser más específicos sobre qué es lo que se debe renderizar, cuándo renderizar y dónde renderizar cada parte del contenido de los components.

El término “render prop” se refiere a una técnica para compartir código entre componentes en React utilizando una propiedad cuyo valor es una función.

Un componente con una render prop toma una función que devuelve un elemento de React y lo llama en lugar de implementar su propia lógica de representación.

Más concretamente, una render prop es una prop que recibe una función que un componente utiliza para saber qué renderizar. Esta técnica hace que el comportamiento que necesitamos compartir sea extremadamente portátil.

class Cat extends React.Component {
  render() {
    const mouse = this.props.mouse;
    return (
      <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
    );
  }
}

class Mouse extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>

        {/*
          En lugar de proporcionar una representación estática de lo que <Mouse> renderiza,
          usa la `render prop` para determinar dinámicamente qué renderizar.
        */}
        {this.props.render(this.state)}
      </div>
    );
  }
}

class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>
        <Mouse render={mouse => (
          <Cat mouse={mouse} />
        )}/>
      </div>
    );
  }
}