react学习第二天笔记
箭头函数
- 箭头函数基础知识
-
var fn=()=>333
; 执行函数fn()的结果是333; -
var fn=(n,m)=>n+m
; 执行函数fn(2,3)的结果是5; -
var fn=(n,m)=>(n+m)
; 执行函数fn(2,3)的结果是5; -
var fn=(n,m)=>{n+m}
; 执行函数fn(2,3)的结果是undefined; 因为大括号内没有设置return返回值; -
var fn=(n,m)=>{ return n+m }
; 执行函数fn(2,3)的结果是5;
-
- header.js文件中箭头函数创建类
- 通过构造函数创建类
class Header extends Component{ render(){ return(我是头部我们都是好孩子2222dddd
) } }
- 函数表达式创建类:箭头函数格式:var fn=()=>();
const Header=()=>(我是头部我们都是好孩子dddd2222dddd
);
- 函数表达式创建类:箭头函数格式:var fn=()=>{return xx}
const Header=()=>{ return(我是头部我们都是好孩子dddddfewew
) };
- 在引入第三方模块时,可以利用解构赋值来提取属性
- 正常情况下,引入react模块,类继承时,使用React.Component
import React from "react"; class Header extends React.Component{ .... }
- 解构赋值
import React,{Component} from "react"; class Header extends Component{ .... }
- 利用ReactDom将元素插入到html页面中,利用解构赋值
- 正常情况下
import ReactDom from "react-dom"; ReactDom.render(
,document.getElementById("app"));
- 解构赋值
import ReactDom,{render} from "react-dom"; render(
,document.getElementById("app"))
- 组件自身数据的改变
- 通过给构造函数设置私有属性state,然后通过this.setState({}),来进行改变;
- 设置私有属性时:
this.state={xxx:xxx}
- 更新状态时:
this.setState({xxx:xxx})
class Header extends React.Component{ constructor(){ super(); //设置初始状态; this.state={ login:false } } //render为一个函数,类原型上的公有属性方法; render(){ //登录之后,显示欢迎谁;没登录,显示先登录; let str=""; if(this.state.login){ str="欢迎你,guobin"; }else{ str="没登录,先登录" } setTimeout(()=>{ //利用定时器,重新设置state;保证this为实例; this.setState({ login:true }) },3000); return ({str}) } } export default Header;
- 组件间:父级给子级传递数据
- 父级通过自定义标签设置自定义属性xxx;来设置数据内容;
- 子级通过props来获取传递的数据内容;
- 自定义标签为构造函数创建,则用this.props.xxx来获取传递过来的数据;
//通过构造函数来创建函数,利用继承创建;通过this.props.xxx来获取父级给子级传的数据; class Header extends Component{ render(){ return(我是头部111 {this.props.context}我们都是好孩子2222dddd
) } }
- 自定义标签通过函数表达式创建,则需要设置形参,然后通过形参获取;
//通过函数表达式来创建函数;利用大括号和return返回值,通过设置形参,通过“形参.xxx”来获取父子给子级传的数据; const Header=(props)=>{ return(我是头部{props.context}) }; //可以使用箭头函数创建类;小括号直接返回值,无需设置return; /*const Header=(props)=>(我是头部{props.context} ); */
- 组件间:子级给父级传递数据
- 父级在构造函数中创建一个公共方法update(){xxx};
- 在父级标签中给子级标签设置属性,用于传递给子级;将update函数的函数体传递给子级;
- 注意:通过bind函数,来保证在传递给子级时,改变this指向为当前实例,确保,无论子级怎么调用,里面的this都是实例;
- 子级通过props接收到父级传的函数体,然后调用执行;
- 在以下例子中,子级中添加事件,事件触发后调用执行update函数,然后再函数中通过事件对象e来获取事件源标签,进而拿到Range的value值,通过state改变自身的状态;进而达到数据改变的效果;
- 注意:es6中事件写成驼峰式写法,如onClick,onChange;
- 代码:
- Footer.js代码
import React from "react"; import "./footer.css"; class Footer extends React.Component{ render(){ return(我是底部 ) } } export default Footer;
- index.js代码
import React from "react"; import ReactDom,{render} from "react-dom"; //引入自定义模块; import Header from "./component/header/header"; import Footer from "./component/footer/footer" import "./css/index.css"; class Index extends React.Component{ constructor(){ super(); this.state={ a:0 } } //原型上的公共方法 update(e){ this.setState({ a:e.target.value }) } render(){ return({/*父级给子级传数据,通过设置自定义属性*/}
- 定义:作为this实例的属性,通过refs能获取一个对象,根据设置在标签上的ref值,作为属性,拿到属性值,属性值为设置的标签元素,可以是自定义的标签组件,也可以是标签元素;
- 以下代码中通过refs来获取不同的标签元素
update(){ //获取h1标签 var H1=this.refs.one; //获取自定义标签Range var Ran=this.refs.two; } render(){ return(这是标题
) }
- 注意:refs获取的标签为组件,不能获取组件中的DOM节点;
- ReactDOM中存在属性findDOMNode,用来获取自定义标签组件中的容器节点;
- 通过解构赋值将findDOMNode属性从ReactDOM中解构出来;如:
import ReactDom,{render,findDOMNode} from "react-dom";
- 注意:组件若由多个元素组成,会拿到外面的父级节点;
//以下节点中,通过findDomNode拿到的DOM节点为:.. class Footer extends React.Component{ render(){ return(我是底部 ) } }
- 通过解构赋值将findDOMNode属性从ReactDOM中解构出来;如:
- 实例:滑动不同的滑块,使对应的值显示在后面
- 注意:组件Range中组成元素只能有一个input元素,这样在通过findDomNode才能拿到它;
- 代码:
- Range.js代码:
import React,{Component} from "react"; class Range extends Component{ render(){ return( ) } } export default Range;
- index.js代码:
import React from "react"; import ReactDom,{render,findDOMNode} from "react-dom"; //引入自定义模块; import Header from "./component/header/header"; import Footer from "./component/footer/footer" import Range from "./component/Range"; import "./css/index.css"; class Index extends React.Component{ constructor(){ super(); this.state={ a:0, b:0, c:0 } } //原型上的公共方法,利用箭头函数,保证函数体内的this为实例;与bind效果相同; update=()=>{ //this.refs.one拿到的是自定义标签Range,通过findDomNode拿到组成自定义标签的DOM节点;即input标签;通过value拿到实时值; this.setState({ a:findDOMNode(this.refs.one).value, b:findDOMNode(this.refs.two).value, c:findDOMNode(this.refs.three).value }) }; render(){ return({/*父级给子级传数据,通过设置自定义属性*/}
{this.state.a} {this.state.b} {this.state.c}) } } render( ,document.getElementById("app"));
- 在子组件中设置父组件传给子组件的数据类型和默认值
- 必须下载模块:prop-types,如:
import propTypes from "prop-types";
- 子组件引入模块;
- 设置数据类型:通过
Footer.propTypes={xxx:xxx}
Footer.propTypes={ context:propTypes.string, age:propTypes.number.isRequired };
- 设置数据默认值:通过
Footer.defaultProps={xxx:xxx}
Footer.defaultProps={ age:16 };
- 必须下载模块:prop-types,如:
- 父组件中设置子组件的节点数据,在子组件中如何获取
- 子组件通过
this.props.children
来获取父组件设置的节点数据 - 获取的数据为一个数组,数组中的每一项为一个对象,即每个标签节点对象;
- 实例对象上存在一个props属性,属性值为一个对象,对象中存在一个children属性,属性值为一个数组,数组中每一项为子节点标签对象,这些子节点标签对象也作为一个对象,存在props属性,属性值为对象,对象中存在children属性,属性值为数组,数组中包含子节点;直至为文本节点;
- 注意:将Index标签插入到页面中,Index中设置的List标签下的标签元素,不会呈现在页面中,页面中呈现的元素取决于List自身return设置的元素,此例子是通过this.props.children拿到Index设置在List标签下的元素对象;然后作为自己的设置;
import React,{Component,Children} from "react"; import ReactDom,{render} from "react-dom"; import "./css/index.css"; //父级组件Index class Index extends Component{ constructor(){ super(); } render(){ return(
-
这是大标题ddd11
eee
这是小图标,document.getElementById("app"));
- 子组件通过
- 获取的节点数据为一个数组,遍历此数组,React身上存在一个Children属性,可以与map配合遍历数组;
- 从React身上解构Children属性;如:
import React,{Children} from "react"
- 配合map遍历数组,匿名函数中获取的item参数为数组中每一个子节点标签对象;
import React,{Component,Children} from "react"; class List extends Component{ render(){ //this.props.children拿到的是一个数组,是实例List下的子节点对象组成的数组; //利用React中的Children属性,调用map方法来遍历此数组,获取每个节点对象 let ListChilds=Children.map(this.props.children,(item)=>{ //item就是拿到的每个标签对象;通过箭头函数,保证this为实例 //返回值为li标签,标签内的内容为节点对象下的子节点;可以是文本节点,也可以是两个子节点对象; return (
- {item.props.children}
) }); return( ListChilds ) } }
- 从React身上解构Children属性;如:
- 实例的属性:主要有3个
- state:自身状态的设置;设置在constructor中,作为私有属性;
属性值为一个对象;
- 设置:constructor中设置;
constructor(){ super(); this.state={ a:0, b:1 }; }
- 更改:
this.setState({a:5})
- 获取:
this.state.a
;
- props:与父级的联系,用于获取父级传给自己的数据;属性值为一个对象;
- 父级设置数据两类:
- 一类是:在自己标签上设置自定义属性xxx,这样在自己的props的属性值对象中就存在一个xxx属性名,属性值为父级设置的自定义属性值;
- 二类是:在自己标签下设置子节点标签,这样在props对象中会存在一个children属性名,属性值为一个数组,数组中的每一项为设置的子节点标签对象;
- 如下代码中:父级Index给子级List设置了自定义属性和子节点标签,获取的props属性值对象中,就存在三个属性,age,bontext,children; 注意:ref属性不算自定义属性;
class Index extends Component{ constructor(){ super(); } render(){ return(
-
这是大标题ddd11
eee
这是小图标
- 父级设置数据两类:
- refs:与子级的联系,用于获取设置在自己的子级身上设置ref值,属性值为一个对象;
- 自身作为父级组件,来设置自己的子级组件,在子级标签上设置ref值,这样自身实例上就存在refs属性,属性值为一个对象,对象中就存在多个属性;
- refs属性值,只针对于自身属性,不是子级属性;
- 注意:在页面render渲染后,直接打印实力this,是可以看到refs属性不为空对象,对象中存在对应的属性,但是页面刚一刷新,打印的refs为空对象,只有在页面刷新后,在执行对应的函数,才能拿到refs中的属性;
- 以下代码中:当页面一刷新,拿到的refs为空对象,只有当点击事件发生后,调用执行update函数,才能拿到refs对应的数据;注意:在子级List实例中不存在父级Index的refs值;
class Index extends Component{ constructor(){ super(); } update(){ //页面刚渲染时,执行此函数,打印的内容为一个空对象; //当点击事件发生后,打印的内容才能为一个对象,对象中存在one属性; console.log(this.refs) } render(){ //实例对象中存在refs属性,属性值为一个对象,对象中的属性名为给子组件设置的ref值,属性值为对应的标签对象; this.update(); //执行函数后,打印的内容为空; console.log(111); //渲染页面只渲染一次,点击事件发生后不会走此代码; return(
-
这是大标题ddd11
eee
这是小图标
- state:自身状态的设置;设置在constructor中,作为私有属性;
属性值为一个对象;
- 例子:Index为父级组件,List为子级组件
- 代码:
//引入模块,结构赋值 import React,{Component,Children} from "react"; import ReactDom,{render} from "react-dom"; //父级组件Index class Index extends Component{ constructor(){ super(); } update(){ //页面刚渲染时,执行此函数,打印的内容为一个空对象; //当点击事件发生后,打印的内容才能为一个对象,对象中存在one属性; console.log(this.refs) } render(){ //实例对象中存在refs属性,属性值为一个对象,对象中的属性名为给子组件设置的ref值,属性值为对应的标签对象; this.update(); //执行函数后,打印的内容为空; console.log(111); //渲染页面只渲染一次,点击事件发生后不会走此代码; return(
-
这是大标题ddd11
eee
这是小图标,document.getElementById("app"));
- 浏览器控制台:打印List实例的结构
文章图片
List实例结构图
- 生命周期
- 定义:页面开始加载到页面渲染显示,之间不同阶段发生不同事;
- 勾子函数:可有可无,不设置,不会影响页面正常加载,为了在页面不同阶段操作不同的事情;
- 开发过程中,都会在componentWillMount函数中获取数据,然后再render渲染到页面上;
- 以下代码运行顺序:
- 页面加载:componentWillMount -> render -> componentDidMount -> 页面显示
- 更新数据:点击事件触发 -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate -> 页面更新;
- 代码:
//引入模块,结构赋值 import React,{Component,Children} from "react"; import ReactDom,{render} from "react-dom"; class Index extends Component{ constructor(props){ //getDefaultProps super(props); //getInitialState this.state={ a:"meihao", destory:false } } //开始加载 componentWillMount(){ alert("componentWillMount"); } //加载完成 componentDidMount(){ alert("componentDidMount"); } //更新state数据 change=()=>{ this.setState({ a:"哈喽" }) }; //是否更新组件 shouldComponentUpdate(){ alert("shouldComponentUpdate"); return true; //必须设置为true,才会更新,否则,不会更新数据; } //开始更新 componentWillUpdate(){ alert("componentWillUpdate") } //更新完毕 componentDidUpdate(){ alert("componentDidUpdate"); } destory=()=>{ alert("ddd") this.setState({ destory:true }) }; //开始销毁 componentWillUnmount(){ alert("componentWillUnmount") } //渲染页面 render(){ if(this.state.destory){ return null; } alert("render"); return(这是标题这是内容:{this.state.a}
更新
销毁) } } render(,document.getElementById("app"));
- 【react学习第二天笔记】react生命周期图
文章图片
react生命周期图
- 父级给子级传递数据时,子级中添加事件触发函数体执行,父级传值时,通过bind保证this执行为实例,也可以通过箭头函数,设置类函数中的公共方法;
- bind设置:在父级给子级传数据时,通过bind()保证this为实例,如:"updates={this.update.bind(this)}"
class Index extends React.Component{ constructor(){ super(); this.state={ a:0, b:0, c:0 } } //原型上的公共方法 update(){ //this.refs.one拿到的是自定义标签Range,通过findDomNode拿到组成自定义标签的DOM节点;即input标签;通过value拿到实时值; this.setState({ a:findDOMNode(this.refs.one).value, b:findDOMNode(this.refs.two).value, c:findDOMNode(this.refs.three).value }) }; render(){ return({/*父级给子级传数据,通过设置自定义属性*/}
{this.state.a} {this.state.b} {this.state.c}) } }
- 箭头函数设置:在父级给子级传数据时,直接传函数体,如:"updates={this.update}"
class Index extends React.Component{ constructor(){ super(); this.state={ a:0, b:0, c:0 } } //原型上的公共方法,利用箭头函数,保证函数体内的this为实例;与bind效果相同; update=()=>{ //this.refs.one拿到的是自定义标签Range,通过findDomNode拿到组成自定义标签的DOM节点;即input标签;通过value拿到实时值; this.setState({ a:findDOMNode(this.refs.one).value, b:findDOMNode(this.refs.two).value, c:findDOMNode(this.refs.three).value }) }; render(){ return({/*父级给子级传数据,通过设置自定义属性*/}
{this.state.a} {this.state.b} {this.state.c}) } }
- 注意:
- return()中如果存在两个标签,必须放在一个div容器中,不能放两个标签;
- 父级设置子级自定义属性时,设置属性值为数字类型,用{}赋值;如:
age={5}
;
推荐阅读
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- 以读攻“毒”唤新活动曹彦斌打卡第二天
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习
- 【韩语学习】(韩语随堂笔记整理)