05. react 初次见面

可莉
• 阅读 551

    到目前为止我们只学习了一种方法来更新UI。调用 ReactDOM.render( ) 方法来改变输出。

    在前面博客中有一个时钟的例子代码:

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

    将时钟封装为Clock组件

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

1. 将函数转换为类

    可以通过5个步骤将函数组件 转换为 类组件

  • 创建一个名称扩展为 React.Component 的ES6 类
  • 创建一个叫做render()的空方法
  • 将函数体移动到 render() 方法中
  • 在 render() 方法中,使用 this.props 替换 props
  • 删除剩余的空函数声明

    使用类就允许我们使用其它特性,例如_局部状态_、生命周期钩子。

    时钟组件被更改为

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

2. 为一个类添加局部状态

    我们通过3个步骤将 date 从属性移动到状态中。

  •  在 render( ) 方法中使用 this.state.date 替换 this.props.date;

  •  添加一个类构造函数来初始化状态 this.state ;

    class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; }

    render() { return (

    Hello, world!

    It is {this.state.date.toLocaleTimeString()}.

    ); } }

  • 元素中移除 date 属性

    class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; }

    render() { return (

    Hello, world!

    It is {this.state.date.toLocaleTimeString()}.

    ); } }

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

    接下来,我们将使 Clock 设置自己的计时器并每秒更新一次。

3. 将生命周期方法添加到类中

    在具有许多组件的应用程序中,在销毁时释放组件所占用的资源非常重要。

    挂载:每当 Clock 组件第一次加载到 DOM 中的时候,我们都会想生产定时器,这在React中被称为挂载(_componentDidMount( ){....}_)

    卸载:每当 Clock 生产的这个 DOM 被移除的时候,我们也会想要清除定时器,这在 React 中被称为卸载( componentWillUnmount( ){....} )。

    这些方法被称作生命周期钩子函数。

    在 componentDidMount( ) 钩子函数中建立定时器,在 componentWillUnmount( ) 钩子函数中卸载计时器。使用 this.setState( ) 来更新组件局部状态:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

    成功:

                    05. react 初次见面

    让我们快速回顾一下发生了什么以及调用方法的顺序:

  1. 当 <Clock /> 被传递给 ReactDOM.render() 时,React 调用 Clock 组件的构造函数。 由于 Clock 需要显示当前时间,所以使用包含当前时间的对象来初始化 this.state 。 我们稍后会更新此状态。

  2. React 然后调用 Clock 组件的 render() 方法。这是 React 了解屏幕上应该显示什么内容,然后 React 更新 DOM 以匹配 Clock 的渲染输出。

  3. 当 Clock 的输出插入到 DOM 中时,React 调用 componentDidMount() 生命周期钩子。 在其中,Clock组件要求浏览器设置一个定时器,每秒钟调用一次 tick()

  4. 浏览器每秒钟调用 tick() 方法。 在其中,Clock 组件通过使用包含当前时间的对象调用 setState() 来调度UI更新。 通过调用 setState() ,React 知道状态已经改变,并再次调用 render() 方法来确定屏幕上应当显示什么。 这一次,render() 方法中的 this.state.date 将不同,所以渲染输出将包含更新的时间,并相应地更新DOM。

  5. 一旦Clock组件被从DOM中移除,React会调用componentWillUnmount()这个钩子函数,定时器也就会被清除。

4. 正确地使用状态 

    关于 setState( ) 这里有三件事情需要知道

4.1 不要直接更新状态

//此代码不会重新渲染组件:
this.state.comment = 'Hello';

//应当使用 setState():
this.setState({comment: 'Hello'});

    构造函数是唯一能够初始化 this.state 的地方。

4.2 状态更新可能是异步的

    React 可以将多个setState() 调用合并成一个调用来提高性能。

    因为 this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。

//此代码可能无法更新计数器:
this.setState({
  counter: this.state.counter + this.props.increment,
});

//正确方法是,请使用第二种形式的 setState() 来接受一个函数而不是一个对象。 该函数将接收
//先前的状态作为第一个参数,将此次更新被应用时的props做为第二个参数:
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

4.3 状态更新合并

    当你调用 setState() 时,React 将你提供的对象合并到当前状态。

    状态可能包含一些独立的变量:

constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }

    可以调用 setState()独立更新他们:

 componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
  }

    这里的合并是浅合并,也就是说this.setState({comments})完整保留了this.state.posts,但完全替换了this.state.comments

5. 数据自顶向下流动

    父组件或子组件都不能知道某个组件是有状态还是无状态,并且它们不应该关心某组件是被定义为一个函数还是一个类。

    这就是为什么状态通常被称为局部或封装。 除了拥有并设置它的组件外,其它组件不可访问。

    组件可以选择将其状态作为属性传递给其子组件。

    这通常被称为 自顶向下 或 单向数据流。 任何状态始终由某些特定组件所有,并且从该状态导出的任何数据或 UI 只能影响树中下方的组件。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这