Compartir la funcionalidad entre los componentes de React es una necesidad bastante común. El concepto es que podemos establecer el comportamiento en un lugar y luego extenderlo a diferentes componentes. Los componentes de orden superior son una forma de hacer esto. Sin embargo, hay otra forma de usar una biblioteca llamada Recompose.
Repositorio de GitHub
¿Qué es Recompose?
La documentación nos ayuda a responder que:
Recompose es un cinturón de herramientas React para componentes funcionales y componentes de orden superior. Piense en ello como lodash para React.
Básicamente, es una biblioteca para React que contiene un montón de ayudantes que devuelven diferentes componentes de orden superior, lo cual es bueno porque elimina parte del trabajo duro de definir patrones comunes de React y hacerlos disponibles de inmediato para extenderse a otros componentes.
¿Qué puede hacer exactamente? Bien, repasemos juntos algunos ejemplos.
Agregar estado a componentes funcionales sin estado
Si no puede adivinarlo por el nombre, un componente funcional sin estado no tiene ningún estado. Simplemente acepta accesorios y devuelve la interfaz de usuario a la interfaz.
const Greeting = props =>
<p>
Hello, {props.name}!
</p>
En escenarios en los que desee utilizar el estado en su componente funcional sin estado, debe convertirlo en un componente de clase. Aquí es donde Recompose resulta útil.
Recompose te proporciona la withState()
ayudante para agregar estado a sus componentes funcionales sin estado. Gestiona un valor estatal único. No puede administrar más de un valor de estado en withState()
como lo harás en tu componente de clase. Se pasa una función para actualizar el valor de estado y un valor predeterminado predeterminado opcional.
Así es cómo withState()
está estructurado:
withState(
stateName: string, // the name we call our state
stateUpdaterName: string, // the name of the function to call
initialState: any | (props: Object) => any // optional default state to pass
): HigherOrderComponent
Un contador es un ejemplo común que se usa para demostrar un concepto. Así es como podemos crear un contador súper simple usando Recompose’s withState()
ayudante:
const App = withState("count", "handleCounter", 0)(({ count, handleCounter }) => {
return (
<div>
<p>{count}</p>
<button onClick={() => handleCounter(n => n + 1)}>Increment</button>
<button onClick={() => handleCounter(n => n - 1)}>Decrement</button>
</div>
);
});
Desde el withState()
helper ya está disponible para nosotros, podemos llamarlo de inmediato y proporcionarle los parámetros que necesita. Nuevamente, esos son:
stateName
: El nombre que llamamos a nuestro estadostateUpdaterName
: El nombre de la función a llamarinitialState
: Estado predeterminado opcional para aprobar
Luego, esos parámetros se integran en el marcado de la interfaz de usuario que queremos representar en la interfaz.
Hay otra forma en que podríamos haber creado nuestro componente contador y vale la pena mirar para obtener más práctica en la utilización de un ayudante de Recomposición.
Primero, creamos un componente de orden superior usando withState()
y los parámetros requeridos.
const enhanced = withState("counter", "handleCounter", 0);
A continuación, hacemos el Counter
componente, trabajando en el withState()
parámetros:
const Counter = ({ counter, handleCounter }) => (
<div>
<h1>{counter}</h1>
<button onClick={() => handleCounter(n => n + 1)}>Increment</button>
<button onClick={() => handleCounter(n => n - 1)}>Decrement</button>
</div>
);
Tenga en cuenta que el nombre del estado y la función de actualización se pasa como accesorios al Counter
componente.
Finalmente, creamos nuestro App
componente envolviendo el Counter
componente en el componente mejorado de orden superior.
const App = enhanced(Counter);
Vea el Pen Recompose withState de Kingsley Silas Chijioke (@kinsomicrote) en CodePen.
Aquí hay otro enfoque popular:
const enhanced = withState("count", "handleCounter", 0);
const App = enhanced(({ count, handleCounter }) => {
return (
<div>
<p>{count}</p>
<button onClick={() => handleCounter(n => n + 1)}>Increment</button>
<button onClick={() => handleCounter(n => n - 1)}>Decrement</button>
</div>
);
});
Consulte Pen Recompose withState v2 de Kingsley Silas Chijioke (@kinsomicrote) en CodePen.
Manejar el estado usando withHandlers ()
Recompose también tiene un withHandlers()
ayudante que le permite manejar el estado mediante la definición de funciones que se utilizarán para actualizar el estado de un componente. Y puede usarlo junto con withState()
!
Se trata básicamente de funciones de orden superior que incorporan accesorios y devuelven un controlador de funciones. Analicemos la estructura como hicimos en el ejemplo anterior.
withHandlers({
incrementCounter: props => event => {
event.preventDefault();
props.handleCounter(props.count + 1);
}
})
Primero que nada, hemos identificado incrementCounter
, que estará disponible para nuestros Counter
componente para actualizar el valor de recuento al hacer clic.
A continuación, construimos el contador como lo hicimos antes, como un componente de orden superior utilizando withState()
:
const enhancedState = withState("count", "handleCounter", 0);
Ahora, definimos nuestras funciones poniendo withHandlers()
usar:
const enhancedHandler = withHandlers({
incrementCounter: props => event => {
event.preventDefault();
props.handleCounter(props.count + 1);
},
decrementCounter: props => event => {
event.preventDefault();
props.handleCounter(props.count - 1);
}
});
Hemos construido un componente de orden superior al que llamamos enhancedHandler
y usado withState()
para definir dos manejadores de funciones en él: incrementCounter
y decrementCounter
. Estos controladores contienen parámetros que serán recibidos como accesorios por los componentes que los llamen. Serán necesarios si queremos actualizar el estado del componente definido usando withState()
.
Muy bien, vamos a crear nuestro componente de contador:
const Counter = ({ count, incrementCounter, decrementCounter }) => (
<div>
<h1>{count}</h1>
<button onClick={incrementCounter}>Increment</button>
<button onClick={decrementCounter}>Decrement</button>
</div>
);
¿Mira eso? Se espera que el estado y los controladores se pasen como accesorios al componente contador.
Para hacer uso de los componentes de orden superior que definimos, tenemos que pasar el Counter
componente a enhancedHandler
y envolver eso como un parámetro para enhancedState
.
En otras palabras:
const App = enhancedState(enhancedHandler(Counter));
Vea el Pen Recompose withState & withHandlers de Kingsley Silas Chijioke (@kinsomicrote) en CodePen.
Composición de varios componentes de orden superior
En ese último ejemplo, usamos dos componentes de orden superior. ¿Hay algo mejor para encadenarlos? ¡Definitivamente! Recompose nos proporciona una compose()
ayudante para hacer exactamente eso. Nosotros podemos usar compose()
para crear un componente que componga ambos componentes de orden superior de una sola vez.
const enhanced = compose(
withState("count", "handleCounter", 0),
withHandlers({
incrementCounter: props => event => {
event.preventDefault();
props.handleCounter(props.count + 1);
},
decrementCounter: props => event => {
event.preventDefault();
props.handleCounter(props.count - 1);
}
})
);
Ahora, podemos usar el componente mejorado en nuestro App
componente:
const App = enhanced(({ count, incrementCounter, decrementCounter }) => {
return (
<div>
<p>{count}</p>
<button onClick={incrementCounter}>Increment</button>
<button onClick={decrementCounter}>Decrement</button>
</div>
);
});
Vea Pen Recompose: componga withState y withHandlers de Kingsley Silas Chijioke (@kinsomicrote) en CodePen.
Administrar el estado usando Redux como reductor
Otra cosa buena que hace Recompose es permitirle administrar el estado usando una función reductora (withReducer
). Un reductor actualiza el estado de un componente en respuesta a una acción en particular.
La estructura de la withReducer()
Se ve como esto:
withReducer<S, A>(
stateName: string,
dispatchName: string,
reducer: (state: S, action: A) => S,
initialState: S | (ownerProps: Object) => S
): HigherOrderComponent</S>
El primer parámetro es el nombre del estado. El segundo es el dispatch
método. dispatch
se utilizará para enviar acciones como las que tenemos en Redux. A continuación, tenemos el reducer
y el estado inicial.
En el contexto de nuestro componente de contador, withReducer()
actualizará el estado del recuento: el recuento aumentará con una acción que llamaremos incremento y, a la inversa, el recuento disminuirá con una acción que llamaremos decremento.
Primero, creamos un componente mejorado componiendo withReducer
y withHandlers
.
const enhanced = compose(
withReducer(
"count",
"dispatch",
(state, action) => {
switch (action.type) {
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
default:
return state;
}
},
0
),
withHandlers({
incrementCounter: ({ dispatch }) => e => dispatch({ type: "INCREMENT" }),
decrementCounter: ({ dispatch }) => e => dispatch({ type: "DECREMENT" })
})
);
incrementCounter
y decrementCounter
responderá a eventos DOM y enviará un tipo de acción. El estado se actualizará según el tipo de acción. A continuación, debemos hacer uso de esto en nuestro componente.
const App = enhanced(({ count, incrementCounter, decrementCounter }) => {
return (
<div>
<p>{count}</p>
<button onClick={incrementCounter}>Increment</button>
<button onClick={decrementCounter}>Decrement</button>
</div>
);
});
Vea Pen Recompose – reductor de Kingsley Silas Chijioke (@kinsomicrote) en CodePen.
Bastante ordenado, ¿verdad?
Con suerte, esto le dará una buena idea de qué es Recompose y cómo la gran cantidad de ayudantes de la biblioteca pueden agilizar el desarrollo de React, particularmente cuando se trata de administrar y llamar estados.
Naturalmente, hay mucho más para Recomponer de lo que hemos cubierto aquí. Un escaneo rápido de la documentación de la API mostrará que hay muchos componentes de orden superior que puede poner en uso, según los requisitos de su aplicación. ¡Continúe, construya y no dude en dejar un comentario si tiene alguna pregunta!