React 基础学习---组件&Props(四)

组件的核心

组件允许你将 UI 拆分成独立的可复用的代码片段,并且对每个片段进行独立构思。

组件从概念上类似 JS 函数,它接受任意的入参(“props”),并返回用于描述页面展示内容的 React 元素

函数组件与 class 组件

定义组件最简单的方式就是编写 JS 函数

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

该函数是一个有效的 React 组件,因为它接受唯一带有数据的”props”(代表属性)对象与并返回一个 React 元素,这类组件被称为”函数组件”,因为它本质就是 JS 函数

第二种方法还可以用 ES6 来定义组件

class Welcome extends React.Component {
  render() {
    return <h1>Hello,{this.props.name}</h1>
  }
}

上面两种方法在 React 里是等效的

渲染组件

React 也可以让用户自定义组件

function Welcome(props) {
  return <h1>Hello,{props.name}</h1>
}
const element = <Welcome name="Sara" />
ReactDOM.render(element, document.getElementById('root'))

这段代码最后的渲染结果就是 Sara

  1. 调用 ReactDOM.render()函数传入作为参数

  2. React 调用 Welcome 组件,并将{name:’Sara’}作为 props 传入

  3. Welcome 组件将<h1>Hello,Sara</h1>作为返回值

  4. ReactDOM 将 DOM 高效的更新为<h1>Hello,Sata</h1>

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

组合组件

  • 组件可以在其输出中引用其他组件。这就可以让我们用同一组件来抽象出任何层次的细节。按钮,表单,对话框。甚至整个屏幕的内容.在 React 应用程序中,这些都可以当作组件

  • 例如我们可以多次渲染组件

function Welcome(props) {
  return <h1>Hello,{props.name}</h1>
}
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  )
}
ReactDOM.render(<App />, document.getElementById('root'))

提取组件

全部组件

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img
          className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">{props.author.name}</div>
      </div>
      <div className="Commet-text">{props.text}</div>
      <div className="Commet-date">{formatDate(props.date)}</div>
    </div>
  )
}

这个组件用于描述一个社交网站的评论功能,它接收 author(对象),text(字符串),以及 date(日期)作为 props

该组件由于嵌套关系,变的难以维护。而且很难复用它的个个部分.因此让我们从中提取一些组件出来.

拆分第一步 Avatar 组件

function Avatar(props) {
  return <img src={props.user.avatarUrl} alt={props.user.name} />
}
  • Avatar 不需要知道它在 Commet 组件内部是如何渲染的,因此我们给它的 props 起了一个更通用的名字:user 而不是 author

  • 我们建议从组件自身的角度命名 props 而不是依赖于调用组件的上下文命名

下面针对上面那个做一下调整

function Commet(props){
  return (
       <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author}>
        <div className="UserInfo-name">{props.author.name}</div>
      </div>
      <div className="Commet-text">{props.text}</div>
      <div className="Commet-date">{formatDate(props.date)}</div>
    </div>
  )
}

接下来我们将提取 UserInfo 组件,该组件在用户旁渲染 Avatar 组件

function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">{props.user.name}</div>
    </div>
  )
}

这样进一步简化

function Commet(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">{props.text}</div>
      <div className="Comment-date">{formatDate(props.date)}</div>
    </div>
  )
}

Props 的只读性

组件无论是使用函数声明还是通过 class 声明,都绝对不能修改自身的 props

function sum(a, b) {
  return a + b
}

这样的函数被称为”纯函数”,因为该函数不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果

相反下面这个就不是纯函数

function withdraw(account, amount) {
  account.total -= amount
}

总结

  1. props 里面的数据绝对不能更改

  2. 组件的定义里面必须要有 return,要是一行就不用()要是多行必须加()

  3. 组件里面可以嵌套组件。没有个数限制。为了更好的使用,建议强烈拆分组件


文章作者: 雾烟云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 雾烟云 !
  目录