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

raz*_*or7 51 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 }
      }}/>
    )
  )}/>
)
Run Code Online (Sandbox Code Playgroud)

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

props,获取Component prop,然后获取给你的所有其他道具,并重命名props为,rest这样你就可以避免使用传递给Route render函数的props的命名问题

我对吗?

Ise*_*chO 90

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

你问:

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

props,获取Component道具,然后获取所有其他props给你,并重命名props为,rest这样你就可以避免命名问题与 props传递给路线render功能

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

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

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

最重要的一点是,你不改名propsrest.(并且它也不会与尝试"避免使用props传递给Route render函数命名问题".)

rest === props;
// => false
Run Code Online (Sandbox Code Playgroud)

你只需将你对象上定义的属性的其余部分(因此为什么参数命名为)拉到props一个名为的新参数中rest.


示例用法

这是一个例子.假设我们有一个myObj定义如下的对象:

const myObj = {
  name: 'John Doe',
  age: 35,
  sex: 'M',
  dob: new Date(1990, 1, 1)
};
Run Code Online (Sandbox Code Playgroud)

对于这个例子,可能有助于将其props视为具有相同的结构(属性和值),如图所示myObj.现在,让我们编写以下作业.

const { name: Username, ...rest } = myObj
Run Code Online (Sandbox Code Playgroud)

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

获取name定义的属性myObj并将其值分配给我们调用的新变量Username.然后,取中定义的任何其他属性myObj(,age,sexdob),并收集到分配给我们命名变量的新对象rest.

登录Usernamerestconsole会证实这一点.我们有以下内容:

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

边注

你可能想知道:

为什么要解决component财产只是Component用大写字母"C" 重命名?

是的,这似乎很微不足道.而且,虽然这是一个标准的React实践,但有一个原因,Facebook的所有文档都在其框架上编写.也就是说,利用JSX渲染的自定义组件的大写本身不是一种必要的实践.反应,或者更恰当地说,JSX区分大小写.插入的没有大写首字母的自定义组件不会呈现给DOM.这就是React如何定义自己来识别自定义组件的方式.因此,有没有例子还改名component这是被拉断的特性propsComponent,该<component {...props} />表达式将无法正确渲染.

  • 我只是为你创造了一个赏金,这就是我能做的,享受它:) (7认同)
  • 你应该是那个可以重写 React 文档的人,你的答案显示了你对教学的热情,涵盖了初学者的每一个细节,同时保持一切简单。 (4认同)

Ise*_*chO 9

它允许您props在一个简洁的表达中"传播"所有内容.例如,假设props您的PrivateRoute组件接收到的样子

// `props` Object:
{
  thing1: 'Something',
  thing2: 'Something else'
}
Run Code Online (Sandbox Code Playgroud)

如果你想进一步交班这些项目(,thing1thing2)下降到嵌套的<Component />标签和你不熟悉的物体传播语法,你可能会这样写:

<Component
  thing1={ props.thing1 }
  thing2={ props.thing2 } />
Run Code Online (Sandbox Code Playgroud)

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

<Component { ...props } />
Run Code Online (Sandbox Code Playgroud)

  • *"它允许你用一个简洁的表达方式"传播"你所有的道具."*这是不对的.在`{component:Component,... rest}`*中的`... rest`收集对象`rest`中的所有其他属性.问题是关于"......休息",而不是"{... props}" (3认同)
  • 虽然相关,但不要将 JSX 的 *spread* 语法与 *rest 属性* 混合在一起。 (2认同)

Yil*_*maz 5

让我们保持简单:在 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;
Run Code Online (Sandbox Code Playgroud)

你将传递其余的道具

label={label} placeholder={placeholder} type={type}
Run Code Online (Sandbox Code Playgroud)