react单项数据流

父组件向子组件传递的参数,是不可以在子组件直接修改的,会报错,父组件传给子组件的都是只读属性。

函数式编程

react是函数式编程的框架,优点是1:代码清晰,知道各个部分是干嘛的,优点2:代码更容易测试。

调试工具的安装和使用

_propTypes校验传递的值

import PropTypes from ‘prop-types’
进行校验要在子组件的类的外面

在子组件的类的外面写

MyService.propTypes = {item: PropTypes.string,index: PropTypes.number,remove: PropTypes.func
}

func: 一定要传方法
PropTypes.string.isRequired : 表示一定要传这个,不能不传

默认值

XiaojiejiItem.defaultProps = {avname: '松岛枫'
}

react中,如何决定要不要将部分代码封装成组件

如果 UI 中有一部分被多次使用,或者组件本身就足够复杂,那么它就是一个可提取出独立组件的候选项。

直接复制一下react官网上关于函数组件解析流程的描述

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')
);
  1. <Clock /> 被传给 ReactDOM.render()的时候,React 会调用 Clock 组件的构造函数。因为 Clock 需要显示当前的时间,所以它会用一个包含当前时间的对象来初始化 this.state。我们会在之后更新 state。
  2. 之后 React 会调用组件的render() 方法。这就是 React 确定该在页面上展示什么的方式。然后 React 更新 DOM 来匹配 Clock 渲染的输出。
  3. Clock的输出被插入到 DOM 中后,React 就会调用ComponentDidMount() 生命周期方法。在这个方法中,Clock 组件向浏览器请求设置一个计时器来每秒调用一次组件的 tick() 方法。
  4. 浏览器每秒都会调用一次 tick() 方法。 在这方法之中,Clock 组件会通过调用 setState() 来计划进行一次 UI 更新。得益于setState() 的调用,React 能够知道 state 已经改变了,然后会重新调用 render()方法来确定页面上该显示什么。这一次,render()方法中的 this.state.date 就不一样了,如此以来就会渲染输出更新过的时间。React 也会相应的更新 DOM。
  5. 一旦 Clock 组件从 DOM 中被移除,React 就会调用componentWillUnmount()生命周期方法,这样计时器就停止了。

把组件传递给ReactDOM.render() =>
React调用Clock的构造函数并初始化数据(state) =>
React调用组件的render()方法,更新DOM来匹配Clock渲染的输出 =>
Clock输出被插入到DOM中,调用生命周期,并且执行一个每秒执行一次的tick方法 => tick方法中,clock组件会调用setState来更新UI,得益于setState的调用,react知道state已经改变了,然后重新调用render()来确定页面显示什么

正确地使用state

  1. 不直接修改
  2. 更新可能是异步的,出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。

因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。

// Wrong
this.setState({counter: this.state.counter + this.props.increment,
});// Correct
this.setState((state, props) => ({counter: state.counter + props.increment
}));

单向数据流

组件无法知道其他组件是有状态还是无状态的,state是组件自己私有的,其他组件无法访问,组件可以选择把state作为props向下传递给它的子组件中。组件接收参数时,不知道这个数据是从哪里来的。

发现问题:有状态无状态是啥?

有状态无状态是啥

有状态组件:用class关键字创建的组件,有自己的私有数据state和生命周期函数
无状态组件:用构造function函数创建出来的组件,只有props,没有sate和生命周期函数

无状态组件,由于没有自己的state和生命周期函数,所以运行效率高

什么时候用无状态组价?

组件本身不需要负责UI变化,不包括子组件

事件绑定中this处理的三种办法

1.在组件的constructor中绑定

2.在有状态(class声明的)组件中,用箭头函数

3.在jsx中写,但不推荐这种写法,因为如果该回调函数作为prop传入子组件,这些组件可能进行额外的重新渲染,印象性能。

条件渲染

比较简单就不写太多了

与运算符&&

可以在JSX中嵌入表达式,可以方便地进行元素的条件渲染
在react的if中写循环怎么写?

工作中的场景,当列表的数据大于0时,才渲染列表

<ul>{ this.state.list.length > 0 && this.state.list.map((item, index) => {return <li key={item+index} ><MyService deleteItem={this.remove.bind(this)} index={index} key={item+index} item={item}></MyService></li>})}
</ul>

简单的切换选项卡效果

constructor(props){super(props)this.state={activeVal: 0}}
...省略代码
render(){return (<Fragment><button onClick={this.changeTab.bind(this,0)}>科技新闻</button><button onClick={this.changeTab.bind(this,1)}>娱乐新闻</button><div>{this.activeVal === 0 ? <h1>科技新闻</h1> : <h1>娱乐新闻</h1>}</div></Fragment>)
}
...省略代码...
changeTab(idx){this.setState({activeVal: idx})
}

阻止组件渲染

render方法返回null,就不会进行渲染了。
render方法返回null不会影响组件的生命周期。

列表渲染与key

列表渲染需要有key,因为键是React用来识别DOM元素的唯一方法,如果将一个项目推到列表中或是删除中间的某一项,如果键与前面的相同,React会以为这个新插入的元素和前面的元素是同一个。
案例地址

当没有输入key时,react会默认把index当做key。但这是suboptimal(未达标准的)。

Much better推荐用法:
安装并且使用shortid

var shortid = require('shortid')function createNewTodo (text) {return {id: shortid.generate(),text}
}

参考文章:Index as a key is an anti-pattern

PropTypes

可以设置默认传递参数的类型

import PropTypes from 'prop-types'MyService.propTypes = {item: PropTypes.string,index: PropTypes.number,remove: PropTypes.func
}

ref与ref的坑

  • ref的用法:
// jsx
<input ref={(input)=>this.input = input} onchange={this.inputChange.bind(this)}></input>
...省略代码inputChange(e){this.setData({data: e.target.value})console.log(this.input.clientHeight) // 用了ref绑定,这里可以获得这个绑定dom元素的相关信息
}

ref的坑

<ul ref={(ul)=>{this.ul=ul}}>{this.state.list.map((item,index)=>{return (<XiaojiejieItem key={index+item}  content={item}index={index}deleteItem={this.deleteItem.bind(this)}/>)})}
</ul>

绑定后可以在addList()方法中,获取当前

的值.
addList(){this.setState({list:[...this.state.list,this.state.inputValue],inputValue:''})//关键代码--------------startconsole.log(this.ul.querySelectorAll('div').length)//关键代码--------------end}

这时候打开控制台,会发现length少一个,这是因为setState是一个异步函数,还没等虚拟dom渲染,console.log就已经执行了。

为了解决这个问题,可以使用setState的回调函数

addList(){this.setState({list:[...this.state.list,this.state.inputValue],inputValue:''},()=>{console.log(this.ul.querySelectorAll('div').length)})
}

React生命周期

Initialization:初始化阶段
mounting:挂载阶段
updation:更新阶段
Unmounting:销毁阶段

  • constructor 不算生命周期函数,constructor算构造函数,属于initialization阶段,定义prop和state

mounting阶段

1.componentWillMount(新版本可能废弃不推荐使用):在组件即将被挂载到页面的时刻执行
2.render:state或props发生变化时执行
3.componentDidMount:组件挂载完成时执行

Updation阶段

1.shouldComponentUpdate:组件更新前执行
要求返回一个布尔类型的结果,必须有返回值,这里就直接返回一个true了

shouldComponentUpdate(){console.log('shouldComponentUpdate---组件发生改变前执行')return true
}

如果return 是false的话,这个组件的render就不会执行了

2.componentWillUpdate:这个函数在组件更新之前,shouldComponentUpdate执行之后执行,如果shouldComponentUpdate函数返回值为false,该函数就不会执行了

3.componentDidUpdate:进行更新

执行顺序:

  1. shouldComponentUpdate
  2. componentWillUpdate
  3. render
  4. componentWillUpdate

componentWillReceiveProps:

子组件接收父组件传来的参数,父组render函数重新执行时,这个函数就执行

  • 也就是说这个组件第一次存在于Dom中,函数是不会被执行的;
  • 如果已经存在于Dom中,函数才会被执行。

新的生命周期

https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html

getDerivedStateFromProps

getDerivedStateFromProps在组件实例化后render前被调用。它可以返回一个对象来更新状态,或者返回 null 来表示新的道具不需要任何状态更新。

class Example extends React.Component {static getDerivedStateFromProps(props, state) {// ...}
}

To-do 的性能优化

打开React Developer Tools中的setting,设置highlight Updates

这时候可以看到


当input在修改时,其他无关的组件如<service>组件也被重新渲染,这样会影响性能,因此我们可以利用生命周期函数来进行优化。

知乎问题

为什么vue没有shouldComponentUpdate?

npm install的三种差别

npm install:安装到项目下但不产生依赖
npm install --save:安装到项目下并且产生依赖,可以在package.json中的dependencies中查看
npm install --save-dev:只在开发环境中需要的安装到这里

save是默认的,你什么都不写就相当于写了–save,因此npm install 时默认的时npm install --save

缩写:
npm i -S: npm install --save
npm i -D: npm install --save-dev

参考:
技术胖React教程

Redux

react ui组件和容器组件

ui组件(只负责页面渲染)
容器组件负责逻辑
普通组件
无状态组件(只有render函数的话,就可以用无状态组件了,可以省去生命周期函数,优化代码)

ui组件和无状态组件的区别

// ui组件
import React, { Component } from 'react';
import { Input, Button, List } from 'antd'class TodoListUI extends Component {state = {  }render() { return ( <div style={{marginTop:'10px',marginLeft:'10px'}}><Input value={this.props.inputValue}placeholder="todo info"onChange={this.props.handleInputChange}style={{width:'300px',marginRight:'10px'}}/><Button onClick={this.props.handleBtnClick} type="primary" >提交</Button><Liststyle={{width:'300px',marginTop:'10px'}}bordereddataSource={this.props.list}renderItem={(item, index) => (<List.Item onClick={() => {this.props.handleItemDelete(index)}} >{item}</List.Item>)}/></div>);}
}export default TodoListUI;
// 无状态组件,就是一个函数,当组件只有render函数的时候很适合使用
// 改写上面的ui组件
import React from 'react';
import { Input, Button, List } from 'antd'function TodoListUI = (props) =>{return (<div style={{marginTop:'10px',marginLeft:'10px'}}><Input value={this.props.inputValue}placeholder="todo info"onChange={this.props.handleInputChange}style={{width:'300px',marginRight:'10px'}}/><Button onClick={this.props.handleBtnClick} type="primary" >提交</Button><Liststyle={{width:'300px',marginTop:'10px'}}bordereddataSource={this.props.list}renderItem={(item, index) => (<List.Item onClick={() => {this.props.handleItemDelete(index)}} >{item}</List.Item>)}/></div>)
}export default TodoListUI;

封装全局的加载组件

https://www.cnblogs.com/leiting/p/10531548.html

react学习笔记(二)相关推荐

  1. React学习笔记二:实现一个数字时钟

    <!DOCTYPE html> <html lang="zhm"><head><meta charset="UTF-8" ...

  2. React学习笔记二——react-router

    2019独角兽企业重金招聘Python工程师标准>>> 今天写了一个关于react-router的demo,因为不喜欢下载太多的依赖包,所以就直接引得js,解析会比较慢一些. 首先先 ...

  3. React学习笔记二 通过柯里化函数实现带参数的事件绑定

    class Login extends React.Component {state = {username: '',password: ''}saveFormData = (type) => ...

  4. React学习笔记(二) | 受控组件

    React组件 目标 能够知道受控组件是什么 能够写出受控组件 了解非受控组件 表单处理 受控组件(★★★) HTML中的表单元素是可输入的,也就是有自己的可变状态 而React中可变状态通常保存在s ...

  5. React学习笔记 - 组件Props

    React Learn Note 4 React学习笔记(四) 标签(空格分隔): React JavaScript 三.组件&Props 组件可以将UI切分成一些独立的.可复用的部件,这样你 ...

  6. ES6学习笔记二arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  7. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

  8. [转载]dorado学习笔记(二)

    原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...

  9. react学习笔记1--基础知识

    什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...

  10. PyTorch学习笔记(二)——回归

    PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...

最新文章

  1. UML用例图概要(转)
  2. 【机器学习课程01】李宏毅2020年机器学习课程开课啦!!!
  3. 01_初识Matplotlib、Figure的组成、绘图函数的输入类型、第一个例子(学习笔记)
  4. Qt创建工程及导入资源图片
  5. vue computed使用_vue computed正确使用方式
  6. 【使用注意】Jsoup的select方法
  7. 19-数据持久化-Bind Mounting
  8. git常用命令之log
  9. 消息队列的使用场景(转载c)
  10. 分享个markdownpad2的授权key
  11. Linux7运维视频教程
  12. 1.7 新概念 量词
  13. ecs 导出mysql文件_mysql导出数据库文件
  14. 固态硬盘的计算机需要进行磁盘碎片整理吗,固态硬盘为什么不需要电脑磁盘碎片整理?...
  15. reporting php,php error_reporting函数怎么用
  16. javac.exe 、 java.exe、 javaw.exe 、 javaws.exe有什么区别?
  17. 小程中的web-view缓存问题
  18. 东风风神酷我音乐显示服务器错误,评测:东风风神奕炫GS中控屏幕多媒体系统使用说明...
  19. 叶子结点和分支节点_什么是叶子节点,度?根节点?
  20. TreeSize Free

热门文章

  1. 西门子哪款plc支持c语言,西门子PLC的几种编程语言简单介绍
  2. 安卓如何调出软键盘_系统软键盘Android在外接物理键盘时,如何强制调用系统软键盘?...
  3. 奇迹暖暖登录显示服务器满,奇迹暖暖登录不是全屏
  4. MySQL基础学习(尚硅谷 婷姐)自学笔记_001
  5. 快手科技2020年总收入人民币588亿元,同比增长50.2%
  6. Nginx 配置长连接
  7. python多进程假死
  8. python将pvr格式转换成pvr.ccz的代码
  9. ioi2020集训队作业_IOI2020 集训队作业 Part 3
  10. silverlight ajax调用,基于RIA的AJAX和Silverlight研究与应用