¿Qué significa ... descansar en React JSX?

82

Mirando este ejemplo de React Router Dom v4 https://reacttraining.com/react-router/web/example/auth-workflow , veo que el componente PrivateRoute destruye un apoyo de descanso como este

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    fakeAuth.isAuthenticated ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

Quiero estar seguro de que eso { component: Component, ...rest }significa:

De props, obtenga el accesorio del componente y luego todos los demás accesorios que se le dieron, y cambie el nombre propsa restpara que pueda evitar problemas de nombres con los accesorios pasados ​​a la renderfunción Ruta

Estoy en lo cierto?

razor7
fuente
5
Es una sintaxis no estandarizada pero definida en github.com/tc39/proposal-object-rest-spread
zerkms

Respuestas:

156

Lo siento, me di cuenta de que mi primera respuesta (aunque espero que siga brindando un contexto útil / adicional) no responde a su pregunta. Déjame intentar de nuevo.

Usted pregunta:

Quiero estar seguro de que eso { component: Component, ...rest }significa:

Desde props, obtener el Componentpuntal y luego todos los demás propsque le ha asignado, y el cambio de nombre propsa restlo que puede evitar nombrar a problemas con el propspasado a la Ruta renderfunción

Tu interpretación no es del todo correcta. Sin embargo, según sus pensamientos, parece que al menos es consciente del hecho de que lo que está sucediendo aquí equivale a una especie de desestructuración de objetos (consulte la segunda respuesta y los comentarios para obtener más aclaraciones).

Para dar una explicación precisa, descompongamos la { component: Component, ...rest }expresión en dos operaciones separadas:

  1. Operación 1: Encuentre la componentpropiedad definida en props( Nota : en minúscula c omponent) y asignarla a una nueva ubicación en el estado que llamamos Component( Nota : el capital C omponent).
  2. Operación 2: Luego, tome todas las propiedades restantes definidas en el propsobjeto y recójalas dentro de un argumento llamado rest.

El punto importante es que NO estás cambiando el nombre propsa rest. (Y tampoco tiene que ver con intentar "evitar problemas de nombres con la función propspasada a la ruta render").

rest === props;
// => false

Simplemente está sacando el resto (de ahí por qué el argumento se llama así) de las propiedades definidas en su propsobjeto en un nuevo argumento llamado rest.


Ejemplo de uso

He aquí un ejemplo. Supongamos que tenemos un objeto `myObj` definido de la siguiente manera:
const myObj = {
  name: 'John Doe',
  age: 35,
  sex: 'M',
  dob: new Date(1990, 1, 1)
};

Para este ejemplo, puede ser útil pensar propsque tiene la misma estructura ( es decir , propiedades y valores) que se muestra en myObj. Ahora, escriba la siguiente tarea.

const { name: Username, ...rest } = myObj

La declaración anterior equivale tanto a la declaración como a la asignación de dos variables (o, supongo, constantes). La declaración se puede pensar como:

Tome la propiedad namedefinida en myObjy asigne su valor a una nueva variable que llamamos Username. A continuación, tomar cualesquiera otras propiedades se define en myObj( es decir , age, sexy dob) y les recogerá en un nuevo objeto asignado al nombre de variable nos rest.

El registro Usernamey restel consoleconfirmarían esto. Tenemos lo siguiente:

console.log(Username);
// => John Doe
console.log(rest);
// => { age: 35, sex: 'M', dob: Mon Jan 01 1990 00:00:00 GMT-0800 (PST) }

Nota al margen

Puede preguntarse:

¿Por qué tomarse la molestia de retirar la componentpropiedad solo para cambiarle el nombre Componentcon una letra "C" mayúscula?

Sí, parece bastante trivial. Y, si bien es una práctica estándar de React, hay una razón por la que toda la documentación de Facebook en su marco está escrita como tal. Es decir, capitalizar componentes personalizados renderizados con JSX es menos una práctica per se que una necesidad. Reaccionar, o más correctamente, JSX distingue entre mayúsculas y minúsculas . Los componentes personalizados insertados sin una primera letra en mayúscula no se representan en el DOM. Así es como React se ha definido a sí mismo para identificar componentes personalizados. Por lo tanto, tenía el ejemplo no, además, cambió el nombre del componentpropiedad que fue retirado de propsa Component, la <component {...props} />expresión sería no se visualizará correctamente.

IsenrichO
fuente
5
gran explicación para nosotros novatos!
user2763557
13

Te permite "difundir" todo tu propsen una sola expresión concisa. Por ejemplo, supongamos que lo propsrecibido por su PrivateRoutecomponente se parece a

// `props` Object:
{
  thing1: 'Something',
  thing2: 'Something else'
}

Si desea transferir estos elementos ( es decir , thing1y thing2) a la <Component />etiqueta anidada y no estaba familiarizado con la sintaxis de propagación del objeto , puede escribir:

<Component
  thing1={ props.thing1 }
  thing2={ props.thing2 } />

Sin embargo, la { ...props }sintaxis evita tal verbosidad al permitirle difundir su propsobjeto de la misma manera que uno podría difundir una matriz de valores ( por ejemplo , [...vals]). En otras palabras, la expresión JSX a continuación y la anterior son exactamente equivalentes.

<Component { ...props } />
IsenrichO
fuente
1
Si bien está relacionado, no mezcle la sintaxis de extensión de JSX con las propiedades rest .
Felix Kling
3
"Te permite" difundir "todos tus accesorios en una sola expresión concisa". Eso no está bien. ...restin { component: Component, ...rest } recopila todas las demás propiedades del objeto rest. La pregunta es sobre ...rest, no{...props}
Felix Kling
Como señala Felix, se debe hacer una distinción entre el operador de propagación de objetos (no estándar) en JSX y el operador de propagación rest _ / _ como se define en la especificación ECMAScript 2015. Por un lado, intentar escribir algo como { ...myObj }en un entorno que no sea React ( por ejemplo , la consola del navegador) arrojará un SyntaxError. Sin embargo, la extensión _ / _ del resto de ES6 proporciona un marco conceptual útil en el que pensar en la extensión del objeto de JSX .
IsenrichO
4

Hagámoslo simple: en JavaScript, si un par "clave: valor" es el mismo, obj={account:account}es el mismo que obj={account}. Entonces, al pasar accesorios del componente principal al secundario:

const Input = ({name,label,error, ...rest}) => {
  return (
    <div className="form-group">
      <label htmlFor={name}>{label}</label>
      <input
        {...rest}
        autoFocus
        name={name}
        id={name}
        className="form-control"
        aria-describedby="emailHelp"
      />
    </div>
  );
};
export default Input;

pasarás el resto de accesorios como:

label={label} placeholder={placeholder} type={type}
Yilmaz
fuente