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

IT技术 reactjs react-router
2021-04-21 10:32:48

看看这个 React Router Dom v4 示例https://reacttraining.com/react-router/web/example/auth-workflow我看到PrivateRoute组件像这样解构了一个休息props

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,获取 Component prop,然后获取所有其他给你的 props,并重命名props为 ,rest这样你就可以避免传递给 Routerender函数的 props 的命名问题

我对吗?

3个回答

抱歉,我意识到我的第一个答案(虽然希望仍然提供有用/额外的上下文)并没有回答你的问题。让我再试一遍。

你问:

我想确定这{ component: Component, ...rest }意味着:

From props,获取Componentprop 然后所有其他props给你,并重命名props为,rest这样你就可以避免props传递给 Routerender函数的命名问题

你的解释不太正确。不过,根据您的想法,听起来您至少知道这里发生的事情相当于某种对象解构(请参阅第二个答案和那里的评论以获得更多说明)。

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

  1. 操作1:查找component上定义的属性props注意:小写Ç omponent),并将其分配给状态我们称之为新的位置Component:资本Ç omponent)。
  2. 操作 2:然后,获取对象上定义的所有剩余属性,props并将它们收集在名为 的参数中rest

重要的一点是你没有重命名propsrest. (并且它也与试图“避免props传递给 Routerender函数的命名问题”有关。)

rest === props;
// => false

您只是将对象上定义的属性的其余部分(因此命名为该参数)props转换为名为rest.


示例用法

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

对于此示例,仅将其props视为具有与 中所示相同的结构(属性和值)可能会有所帮助myObj现在,让我们编写以下作业。

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

上面的语句相当于两个变量(或者,我猜是常量)声明赋值该语句可以被认为是:

获取name定义的属性myObj并将其值分配给我们称为 的新变量Username然后,获取在myObj上定义的任何其他属性agesex并将dob它们收集到分配给我们命名的变量的新对象中rest

记录Usernamerestconsole将确认这一点。我们有以下几点:

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

边注

你可能想知道:

为什么要费尽心思将component财产撤下,却只Component用大写字母“C”将其重命名

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

我只是为你创造一个赏金,这是我所能做的,享受它:)
2021-05-28 10:32:48
您应该是可以重写 React 文档的人,您的回答显示了对教学的热情,涵盖初学者的每一个细节,同时保持一切简单。
2021-06-08 10:32:48

它允许您props在一个简洁的表达中“传播”所有内容例如,让我们假设props您的PrivateRoute组件接收到的看起来像

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

如果您想进一步将这些项目(,thing1thing2)传递给嵌套<Component />标记并且您不熟悉对象扩展语法,您可以编写:

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

但是,{ ...props }语法允许您避免了这种冗长传播你的props对象以相同的方式一个可能蔓延值(数组例如[...vals])。换句话说,下面的 JSX 表达式和上面的完全等效。

<Component { ...props } />
正如 Felix 所指出的,JSX 中的(非标准)对象扩展运算符与 ECMAScript 2015 规范中定义rest_/_spread运算符之间存在区别一方面,尝试{ ...myObj }在非 React 环境(例如,浏览器控制台)中编写类似的东西会抛出一个SyntaxError. 尽管如此,ES6 的rest_/_spread提供了一个有用的概念框架,可以在其中思考 JSX 的对象spread
2021-06-09 10:32:48
虽然相关,但不要将 JSX 的传播语法与其余属性混合
2021-06-11 10:32:48
“它允许您以一个简洁的表达方式“传播”所有道具。” 那是不对的。...restin{ component: Component, ...rest } 收集对象中的所有其他属性rest问题是关于...rest, 不是{...props}
2021-06-12 10:32:48

让我们保持简单:在 JavaScript 中,如果“键:值”对相同, obj={account:account}则与obj={account}. 因此,当将props从父组件传递给子组件时:

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;

你将传递其余的props

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