前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >组件&Props

组件&Props

作者头像
landv
发布2019-12-10 18:08:15
6510
发布2019-12-10 18:08:15
举报
文章被收录于专栏:landv

组件允许你将Ui拆分为独立可复用的代码片段,并对每个片段进行独立构思。本指南只在介绍组件的相关概念。你可以参考详细组件 API

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

函数组件与class组件

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

代码语言:javascript
复制
function Welcome(props) {
    return <h1>Hello,{props.name}</h1>
}

该函数是一个有效的REACT组件,因为它接受唯一带有数据的“props”(代表属性)对象和并返回一个REACT元素。这类组件被成为“函数组件”,因为它本质上就是JavaScript函数。

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

代码语言:javascript
复制
class Welcome extends React.Component{
    render(){
        return <h1>hello,{this.props.name}</h1>
    }
}

上述两个组件在REACT里是等效的。

我们将在下一章节中讨论关于class的额外特性。在那之前,为了保持示例简单明了,将使用函数组件。

渲染组件

之前,我们遇到的REACT元素都只是DOM标签:

代码语言:javascript
复制
const element = <div />;

不过REACT元素也可以是用户自定义的组件:

代码语言:javascript
复制
const element = <Welcome name="Sara" />;

当REACT元素为用户自定义组件时,它会将JSX所接收的属性转换为单个对象传递给组件,这个对象被称之为PROPS。

例如,这段代码会在页面渲染“Hello,Sara”:

代码语言:javascript
复制
function Welocome(props) {
    return <h1>Hello,{props.name}</h1>
}

const element =<Welcome name="Sara"/>;

ReactDOM.render(
    element,
    document.getElementById('root')
)

让我们来回顾一下这个例子中发生了什么:

1、我们调用ReactDOM.render()函数,并传入<Welcome name="Sara"/>作为参数。

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

3、Welcome组件将<h1>Hello,Sara</h1>元素作为返回值。

4、React DOM 将DOM高效地更新为<h1>Hello,Sara</h1>。

代码语言:javascript
复制
注意: 组件名称必须以大写字母开头。

React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div /> 代表 HTML 的 div 标签,而 <Welcome /> 则代表一个组件,并且需在作用域内使用 Welcome。

你可以在深入 JSX中了解更多关于此规范的原因。

组合组件

组件可以在其输出中引用其他组件。这就可以让我们同一组件来抽象出任意层次的细节。按钮,表单,对话框,甚至整个屏幕的内容:在REACT应用程序中,这些通常都会以组件形式表示。

例如,我们可以创建一个可以多次渲染Welcome组建的APP组件:

代码语言:javascript
复制
function Welocome(props) {
    return <h1>Hello,{props.name}</h1>
}

function App() {
    return(
        <div>
            <Welcome name="Sara"></Welcome>
            <Welcome name="Cahal"></Welcome>
            <Welcome name="Edite"></Welcome>
        </div>
    );
}

ReactDom.render(
    <App/>,
    document.getElementById('root')
)

通常来说,每个新的REACT应用程序的顶层组件都是APP组件。但是,如果你将REACT集成到现有的应用程序中,你肯能需要使用像Button这样的小组件,并自下而上地将这类组件逐步应用到视图层的每一处。

提取组件

将组件拆分为更小的组件。

例如,参考如下Comment组件:

代码语言:javascript
复制
function formatDate(date) {
  return date.toLocaleDateString();
}

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="Comment-text">{props.text}</div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

const comment = {
  date: new Date(),
  text: 'I hope you enjoy learning React!',
  author: {
    name: 'Hello Kitty',
    avatarUrl: 'https://placekitten.com/g/64/64',
  },
};
ReactDOM.render(
  <Comment
    date={comment.date}
    text={comment.text}
    author={comment.author}
  />,
  document.getElementById('root')
);

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

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

首先,我们将提取Avatar组件:

代码语言:javascript
复制
function Avatar(props) {
    return(
        <img className="Avatar"
            src={props.user.avatarUrl}
            alt={props.user.name}
        />
    );
}

Avatar不需要知道它在Comment组件内部是如何渲染的。因此,我们给它的props起了一个更通用的名字:user,而不是author。

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

我们现在针对Comment做些小调整:

代码语言:javascript
复制
function Comment(props) {
    return(
        <div className="Comment">
            <div className="UserInfo">
                <Avatar user={props.author} />
                <div className="UserInfo-name">
                    {props.author.name}
                </div>
            </div>
            <div className="Comment-text">
                {props.text}
            </div>
            <div className="Comment-date">
                {formatDate(props.date)}
            </div>
        </div>
    );
}

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

代码语言:javascript
复制
function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}

进一步简化Comment组件:

代码语言:javascript
复制
function Comment(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>
  );
}

最初看上去,提取组件可能是一件繁重的工作,但是,在大型应用中,构建可复用组件库是完全值得的。根据经验来看,如果Ui中有一部分被多次使用(Button,Panel,Avatar),或者组件本身就足够复杂(APP,FeedStory,Comment),那么它就是一个可复用组件的候选项。

PROPS的只读性

组件无论是使用函数声明还是通过Class声明,都决不能修改自身的PROPS。来看下这个sum函数:

代码语言:javascript
复制
function sum(a,b) {
    return a+b;
}

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

相反,下面的这个函数则不是纯函数,因为它更改了自己的入参:

代码语言:javascript
复制
function withdraw(account,amount) {
    account.total -=amount;
}

REACT非常灵活,但它也有一个严格的规则:

所有REACT组件都必须像纯函数一样保护它们的PROPS不被更改。

当然,应用程序的UI是动态的,并会伴随时间的推移而变化。在下一章节中,我们将介绍一种新的概念,称之为“state”。在不违反上述规则的情况下,state允许REACT组件随用户操作、网络响应或者其他变化而动态更改输出内容。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数组件与class组件
  • 渲染组件
  • 组合组件
  • 提取组件
  • PROPS的只读性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档