Подтвердить что ты не робот

Беспроблемный оператор распространения JSX

Учитывая этот пример кода из документов React:

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;

Я искал то, что на самом деле оценивает ...props, что и есть:

React.__spread({}, props)

Что, в свою очередь, оценивается как {foo: x, bar: y}.

Но мне интересно, почему я не могу это сделать:

var component = <Component props />;

Я не понимаю, что такое точка оператора спреда.

4b9b3361

Ответ 1

Это поможет сделать ваш код более сжатым - поскольку props является объектом, оператор спрединга принимает свойства объекта, который вы передаете, и применяет их к компоненту. Таким образом, компонент будет иметь свойства a foo со значением x и a bar со значением y.

Это будет то же самое, что:

var component = <Component foo={props.foo} bar={props.bar} />;

короче

Ответ 2

Один из лучших обзоров о том, как синтаксис синтаксиса "объект-отдых" работает с реакцией, публикуется в reactpatterns.com:

Атрибуты распространения JSX

Атрибуты распространения - это функция JSX. Это синтаксический сахар для передачи всех свойств объекта в качестве атрибутов JSX.

Эти два примера эквивалентны.

// props written as attributes
<main className="main" role="main">{children}</main>

// props "spread" from object
<main {...{className: "main", role: "main", children}} />

Используйте это для пересылки props в базовые компоненты.

const FancyDiv = props =>
  <div className="fancy" {...props} />

Теперь я могу ожидать, что FancyDiv добавит соответствующие атрибуты, а не те, которые он не имеет.

<FancyDiv data-id="my-fancy-div">So Fancy</FancyDiv>

// output: <div className="fancy" data-id="my-fancy-div">So Fancy</div>

Имейте в виду, что порядок имеет значение. Если props.className определено, он будет clobber className, определяемый FancyDiv

<FancyDiv className="my-fancy-div" />

// output: <div className="my-fancy-div"></div>

Мы можем сделать FancyDiv className всегда "выигрышем", разместив его после реквизита распространения ({...props}).

// my `className` clobbers your `className`
const FancyDiv = props =>
  <div {...props} className="fancy" />

Вы должны обработать эти типы реквизитов изящно. В этом случае я объединю автора props.className с className, необходимым для стилизации моего компонента.

const FancyDiv = ({ className, ...props }) =>
  <div
    className={["fancy", className].join(' ')}
    {...props}
  />

- цитируется reactpatterns.com @chantastic


Еще один хороший обзор был опубликован в блоге блога Babeljs Реагировать на ES6 + от Стивена Люшера:

Атрибуты деструктурирования и распространения

Часто при компоновке компонентов мы можем захотеть передать большинство реквизитов родительских компонентов на дочерний компонент, но не все из них. В сочетании с деструктурированием ES6 + с атрибутами распространения JSX это становится возможным с уверенностью:

class AutoloadingPostsGrid extends React.Component {
  render() {
    const {
      className,
      ...others  // contains all properties of this.props except for className
    } = this.props;
    return (
      <div className={className}>
        <PostsGrid {...others} />
        <button onClick={this.handleLoadMoreClick}>Load more</button>
      </div>
    );
  }
}

- цитируется "Блог BabelJS.org - Реагировать на ES6 +" от Стивена Лушера