React文档笔记day03

2018-03-27  本文已影响11人  爆炸的白菜君

组件和属性

组件(components)的作用是可以把UI界面分成很多模块,并且提高复用性。就是移动端所谓的自定义控件。

组件就像一个js函数一样可以接受参数就是(props)然后返回界面上面的element元素。

组件分为函数型组件和类型组件

函数型组件

最简单的组件就是写一个js函数

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

上面这个就是一个函数型的组件,因为这个代码块接受了一个props参数返回了React节点元素

类型的组件

也可以使用ES6标准的类去实现一个组件

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

上面代码定义了一个Welcome类,继承(extends)自React.Component
以后如果是用类型的组件都需要继承这个组件
类中有一个render方法,返回的也是一个React组件

类组件相比较与函数组件有更多的功能会在下一节讲到。后面为了方便都会以函数组件作为🌰

渲染一个组件

当React遇见一个用户自定义的组件的时候,会把标签的属性作为一个对象传递给这个组件,这个对象称之为“props”
🌰

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

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

还是拆分来讲

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

是定义了一个Welcome的组件,传入的是props对象,返回一个h1标签,标签里面会把传进来的props的name属性动态的和hello拼接在一起。

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

创建一个Welcome组件,并且传入name="Sara",最后赋值给element

注意这里的虽然 只是有一个name="Sara",但是React会把Welocome的左右属性打包成一个对象传进React,打包成的对象就是props

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

这是渲染语句,和前一篇里面讲解的差不多,就不赘述了。

组件可以嵌套使用

组件的嵌套使得我们可以把一个组件作为另一个组件的返回值。
例如可以是创建一个App组件,这个组件里面可以使用对个Welcome组件

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

这个 Comment 组件里面有很复杂的标签嵌套,看起来头疼脑胀。
我们可以再这些变迁中提取组件,是代码看起来更加的整洁简单
先看看这段组件的运行效果


image.png

现在开始提取组件
首先可以把用户头像部分提取出来

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />

  );
}

那么整体效果是这样的

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>
  );
}

然后可以把用户信息组成一个组件

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

提取之后的效果

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>
  );
}

现在在看是不是觉得精简了很多?
下面全部代码,可以看看到现在的效果就体现了面向对象的封装性
把固定功能的代码块集合在一个区间内
而且阅读起来简单易懂,思路清晰

function formatDate(date) {
  return date.toLocaleDateString();
}

function Avatar(props) {
  return (
    <img
      className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}

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

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>
  );
}

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

props是只读的不可修改

例子🌰

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

这个函数称为“pure”,没有改变输入值,并且传入相同的值返回值永远是一样的,
相反,下面各个函数就不是“ pure”函数

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

React是非常灵活的,但是有一条准则

All React components must act like pure functions with respect to their props.
所有的React组件必须像纯粹函数一样行事,不能修改输入的props属性。

当然,UI界面都输动态的,在下一篇我们将会学习另一个React属性,state,这个属性允许动态的输出但不违反原则。

上一篇下一篇

猜你喜欢

热点阅读