概念

组件,从概念上类似于Javascript函数。它接受任意的入参(即”props”),并返回用于描述页面展示内容的React元素。
组件 包括了 函数组件 和class组件。
1.定义组件最简单的方式就是编写JavaScript 函数,该函数是一个有效的React组件,因为它接受唯一带有数据的”props”(代表属性)对象与并返回一个React 元素。这类组件称为”函数组件”,因为它本质上就是JavaScript函数。

  1. function Welcome(props){
  2. return <h1>Hello,{props.name}</h1>
  3. }

你同时还可以使用ES6的class 来定义组件

  1. class Welcome extends React.Component {
  2. render(){
  3. return <h1>Hello,{this.props.name}<h1>
  4. }
  5. }

当React元素为用户自定义组件时,它会将JSX所接受的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称为”props”.
下面这个例子:
1.我们调用了ReactDOM.render()函数,并传入 作为参数
2.React调用Welcome组件,并将{name:’Sara’}作为props传入。
3.Welcome组件将

Hello,Sata

元素作为返回值。
4.React DOM将DOM高效的更新为

Hello,Sara


注意:组件名称必须以大写字母开头
React 会将以小写字母开头的组件视为原生的DOM标签。例如
代表HTML的div标签,而则代表一个组件,并且需在作用域内使用Welcome.

  1. function Welcome(props){
  2. return <h1>Hello,{props.name}</h1>
  3. }
  4. const element =<Welcome name='sara' />
  5. ReactDOM.render(element,document.getElementById('root'))

========================================================================

组合 VS 继承

有些组件无法提前知晓他们子组件的具体内容,在Sidebar(侧边栏)和Dialog(对话框)等展现通用容器的组件中特别容易遇到这种情况。
建议这些组件使用一个特殊的children prop来将他们的子组件传递到渲染结果中:
JSX 标签中的所有内容都会作为一个children prop传递给FancyBorder 组件。因为FancyBorder将{props.children} 渲染在一个

中,被传递的这些子组件最终都会出现在输出结果中。

  1. function FancyBorder(props){
  2. return (<div className ={'a a-'+props.color}> {props.children}</div>)
  3. }
  4. //这使得别的组件通过JSX嵌套,将任意组件作为子组件传递给他们。
  5. function WelcomeDialog(){
  6. return <FancyBorder color='blue'>
  7. <h1> Welcome</h1>
  8. <p> Thank you for visiting our spacecraft!</p>
  9. </FancyBorder>
  10. }
  11. ReactDOM.render(<WelcomeDialog />,document.getElementById('root'))

少数情况下,你可能需要在一个组件中预留几个洞。这种情况下,我们可以不使用children,而是自行约定:将所需内容传入props,并使用响应的prop
和 之类的React 元素本质就是对象(object),所以你可以把他们当作props,像其他数据一样传递。这种方法可能使你想起别的库中”槽(slot)”的概念,但在React 中没有“槽”这一概念的限制,你可以将任何东西作为 props 进行传递。

  1. function SplitPane(props){
  2. return (
  3. <div className="SplitPane">
  4. <div>{props.left}</div>
  5. <div>{props.right}</div>
  6. </div>
  7. )
  8. }
  9. function App(){
  10. return (
  11. <SplitPane left ={<Contacts />} right={<Chat />}
  12. )
  13. }
  1. function FancyBorder(props) {
  2. return (
  3. <div className={'FancyBorder FancyBorder-' + props.color}>
  4. {props.children}
  5. </div>
  6. );
  7. }
  8. function Dialog(props) {
  9. return (
  10. <FancyBorder color="blue">
  11. <h1 className="Dialog-title">
  12. {props.title}
  13. </h1>
  14. <p className="Dialog-message">
  15. {props.message}
  16. </p>
  17. </FancyBorder>
  18. );
  19. }
  20. function WelcomeDialog() {
  21. return (
  22. <Dialog
  23. title="Welcome"
  24. message="Thank you for visiting our spacecraft!" />
  25. );
  26. }
  27. ReactDOM.render(
  28. <WelcomeDialog />,
  29. document.getElementById('root')
  30. );