在 React JSX 中... rest 是什么意思?

看看这个反应路由器 Dom v4示例 https://reacttraining.com/react-router/web/example/auth-workflow,我看到 PrivateRoute组件解构了一个像这样的休息道具

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

我想确定{ component: Component, ...rest }的意思是:

props中获取组件道具,然后所有其他道具都会给您,并将 props重命名为 rest,这样您就可以避免传递给 Route render函数的道具的命名问题

我说的对吗?

92530 次浏览

它允许你在一个简洁的表达中“传播”你所有的 props。例如,让我们假设 PrivateRoute组件接收的 props类似于

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

如果您想进一步将这些项目(也就是说。thing1thing2)传递给嵌套的 <Component />标记,而且您不熟悉 物体扩散语法,那么您可以写:

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

然而,{ ...props }语法通过允许您使用与使用值数组(例如:。[...vals])相同的方式 传播您的 props对象来避免这种冗长。换句话说,下面的 JSX 表达式和上面的表达式是完全等价的。

<Component { ...props } />

Sorry, I realized my first answer (while hopefully still providing useful/additional context) doesn't answer your question. Let me try again.

你问:

我想确定 { component: Component, ...rest }的意思是:

From props, get the Component prop and then all other props given to 然后将 props重命名为 rest,这样就可以避免使用 传递给路由 render函数的 props

你的解释并不完全正确。不过,基于你的想法,听起来你至少意识到了这里发生的事情相当于某种 object destructuring(参见第二个答案和评论以获得更多澄清)。

为了给出准确的解释,让我们将 { component: Component, ...rest }表达式分解为两个单独的操作:

  1. 操作1: 查找在 props上定义的 component属性(Note: 小写的 C分量) ,并将其分配到我们称为 Component的状态下的一个新位置(Note: 大写的 C分量)。
  2. 操作2: 然后,获取在 props对象上定义的所有 剩下的属性,并将它们收集到一个名为 rest的参数中。

重要的一点是,您没有将 props重命名为 rest。(而且这也与试图“避免传递给路由 render功能的 props的命名问题”无关。)

rest === props;
// => false

您只需将在 props对象上定义的属性的 剩下的(因此该参数的名称就是 that)提取到一个名为 rest的新参数中。


示例用法

这里有一个例子,假设我们有一个对象‘ myObj’定义如下:
const myObj = {
name: 'John Doe',
age: 35,
sex: 'M',
dob: new Date(1990, 1, 1)
};

对于这个示例,只考虑 props具有与 myObj中所示相同的结构(也就是说。、属性和值)可能会有所帮助。现在,让我们写下面的作业。

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

上面的陈述相当于两个变量(或者,我猜,常量)的 声明任务。这句话可以这样理解:

获取在 myObj上定义的属性 name,并将其值赋给新的 variable we call Username. Then, take whatever other properties were 定义在 myObj(也就是说。agesexdob)并收集它们 转换成一个新的对象,分配给我们命名为 rest的变量。

Usernamerest记录到 console可以证实这一点。我们有以下信息:

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

Side Note

You may wonder:

为什么要大费周章地取走 component的财产 只是把它改名为 Component大写字母“ C”?

是啊,看起来很微不足道。而且,虽然这是一个标准的 React 实践,但是它的框架中的所有 Facebook 的文档都是这样编写的是有原因的。也就是说,大写用 JSX 呈现的自定义组件本身并不是一种实践,而是一种必要。反应,或更恰当地说,JSX 是区分大小写的。没有大写首字母插入的自定义组件不会呈现给 DOM。这就是 React 定义自身以识别定制组件的方式。因此,如果示例没有另外将从 props提取的 component属性重命名为 Component,则 <component {...props} />表达式将无法正确呈现。

让我们保持简单: 在 JavaScript 中,如果一个 “键: 值”对是相同的, obj={account:account}obj={account}是一样的,所以当 道具从父组件传递到子组件时:

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;

你将以下列方式通过 剩下的道具考试:

label={label} placeholder={placeholder} type={type}