Беспроблемный оператор распространения 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 />;
Я не понимаю, что такое точка оператора спреда.
Ответы
Ответ 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 +" от Стивена Лушера