这是什么意思......在React JSX中休息

时间:2017-04-19 00:29:48

标签: reactjs react-router

看看这个React Router 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,获取Component prop,然后获取给您的所有其他道具,并将props重命名为rest,这样您就可以避免使用传递给Route的道具的命名问题{ {1}}功能

我是对的吗?

3 个答案:

答案 0 :(得分:68)

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

你问:

  

我想确定{ component: Component, ...rest }表示:

     

props,获取Component道具,然后获取所有其他props   您,并将props重命名为rest,以便您可以避免命名问题   props已传递到路由render函数

你的解释不太正确。根据你的想法,听起来你至少知道这里发生的事情等于某种object destructuring(见第二个答案并在那里发表评论以获得更多澄清)。

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

  1. 操作1:查找component上定义的props属性(注意:小写 c omponent)和将其分配到我们称之为Component的州的新位置(注意:资本 C omponent)。
  2. 操作2:然后,获取props对象上定义的所有剩余属性,并将其收集在名为rest的参数中。
  3. 重要的是,您不要将props重命名为rest。 (并且它也不会与尝试&#34;避免使用传递给路由props函数的render命名问题&#34 ;.)

    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即。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) }
    

    旁注

    你可能想知道:

      

    为什么要解决component财产问题   只能用大写字母&#34; C&#34;?

    重命名Component

    是的,这看起来很微不足道。而且,虽然它是标准的React实践,但其框架上的所有Facebook's documentation都是这样写的。也就是说,利用JSX渲染的自定义组件的大写本身不是一种必要的实践。反应,或更恰当地JSX is case-sensitive。插入的没有大写首字母的自定义组件不会呈现给DOM。这就是React如何定义自己以识别自定义组件。因此,如果示例未另外重命名从component移至props的{​​{1}}属性,则Component表达式将无法正确呈现。

答案 1 :(得分:7)

它允许你传播&#34;所有props都在一个简洁的表达式中。例如,我们假设props组件收到的PrivateRoute似乎是

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

如果您想进一步将这些项目(thing1thing2)向下移动到嵌套的<Component />标记,那么您就不会这样做了。熟悉object spread语法,您可以写:

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

但是,{ ...props }语法允许您传播您的props对象,就像人们可能传播一个数组一样,从而避免了这种冗长值(例如[...vals])。换句话说,下面和上面的JSX表达式完全相同。

<Component { ...props } />

答案 2 :(得分:0)

让我们保持简单。在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}