什么...在 React JSX 中休息?

2022-08-30 05:12:22

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

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

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

从 中获取组件道具,然后将所有其他道具都提供给您,并重命名为,以便您可以避免传递给 Route 函数的道具的命名问题propspropsrestrender

我说的对吗?


答案 1

对不起,我意识到我的第一个答案(虽然希望仍然提供有用/额外的上下文)不能回答你的问题。让我再试一次。

你问:

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

从 中获取道具,然后所有其他属性都交给您,并重命名为,以便您可以避免传递到 Route 函数的命名问题propsComponentpropspropsrestpropsrender

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

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

  1. 操作 1:找到定义在 上的属性(注意:小写的 component),并将其分配到我们调用的状态中的新位置(注意:大写的 Component)。componentpropsComponent
  2. 操作 2:然后,获取对象上定义的所有剩余属性,并将它们收集在名为 的参数中。propsrest

重要的一点是,您没有重命名为 。(这也与尝试“避免传递给 Route 函数的命名问题”无关。propsrestpropsrender

rest === props;
// => false

您只是将对象上定义的属性的其余部分(因此为什么参数被命名为 that)拉到一个名为 的新参数中。propsrest


用法示例

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

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

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

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

获取 定义在 上的属性,并将其值分配给我们称为 的新变量。然后,获取定义的任何其他属性( , 和 ),并将它们收集到分配给我们命名的变量的新对象中。namemyObjUsernamemyObjagesexdobrest

日志记录和到将确认这一点。我们有以下方面:Usernamerestconsole

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

附注

您可能想知道:

为什么要经历拉出房产的麻烦,却用大写字母“C”重新命名?componentComponent

是的,这似乎微不足道。而且,虽然这是一个标准的 React 实践,但 Facebook 在其框架上的所有文档都是这样编写的,这是有原因。也就是说,将使用 JSX 呈现的自定义组件大写本身与其说是一种做法,不如说是必需的。React,或者更准确地说,JSX是区分大小写的。插入的不带大写首字母的自定义组件不会呈现给 DOM。这就是 React 如何定义自己来识别自定义组件。因此,如果该示例没有另外重命名从 中拉取的属性,表达式将无法正确呈现。componentpropsComponent<component {...props} />


答案 2

它允许您在一个简洁的表达式中“传播”所有你。例如,假设组件接收到的内容如下所示propspropsPrivateRoute

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

如果你想进一步把这些项目(和)交给嵌套标签,并且你不熟悉对象传播语法,你可以这样写:thing1thing2<Component />

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

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

<Component { ...props } />