React
2019-06-06 11:38
1406 查看
- 虚拟DOM 浏览器中的概念,用JS对象来表示页面上的元素,并提供了操作DOM对象的API
- 是框架的概念,是程序员用JS对象来模拟页面上的DOM元素和DOM嵌套
- 为了实现页面的高效更新
-
tree
function createElement(tag, props, children) { return { tag, props: {...props}, children: [...children] } } let p = createElement("p", { class: "p" }, ["自信"]) let createEle = createElement("div", { id: "wrap", class: "wrap", style: { width: "100", height: "100", background: "cornflowerblue" } }, ["1701B",p])
- 把虚拟的dom转成真实的dom,并且把它渲染到页面
render(createEle, document.getElementById("root")) //必须是id function render(vTree, root) { //渲染到页面 let dom = createDom(vTree) root.appendChild(dom) //把虚拟的dom转成真实的dom function createDom(vTree) { let { tag, props, children } = vTree; let dom = document.createElement(tag) Object.entries(props).forEach(item => { let [key, val] = item; //如果属性值是css样式 if (typeof val == "object") { Object.entries(val).map(i => i[0] + ":" + i[1]).join(";") } dom.setAttribute(key, val) }) //添加子节点 if (children) { children.forEach(item => { //递归调用 let text = typeof item == "string" ? document.createTextNode(item) : createDom(item) dom.appendChild(text) }) } return dom } }
- Object.entries 打印结果是
- React 创建react元素
React.createElement(string/function/reactClass,props,children)
- ReactDOM 虚拟dom变为真实的dom节点
ReactDOM.render(vnode,rootdom)
- JSX 是JavaScript对象
符合xml规范的JS语法 - 并不是直接把jsx渲染到页面,而是内部通过babel转换成createElement形式,在渲染
- 注释
{/**/}
- 用className添加class类名
- htmlFor替换label中的for属性
- 标签必须成对出现,单标签必须闭合
- jsx运行更快,在编译js代码后进行了优化,更加简单快捷,安全
- 规则: 一个react元素必须要有一个根节点
- 遇见<>解析html模板,遇见</>解析结束
- 遇见{开始解析js,遇见}js解析结束
-
可复用的html结构
相当于使用构造函数,来创建组件,必须要向外return一个合法的JSX创建的虚拟DOM
class 组件名称 extends React.Component{ constructor(props){ //可写可不写,写了必须调用super super(props) //定义组件内部的状态 this.state = { count:8 } }, render(){ let {grade} = this.props let {count} = this.state return <div> //创建的组件 <h3>{grade}</h3> <div>{count}</div> <button onClick={() => { //修改组件内部的状态,必须通过setState()来修改,是个异步的方法 this.setState({ count:this.state.count+1 },() => { console.log(this.state.count) }) }}>点击</ button> </div> } }
- setState 是一个异步方法,第一个参数是要合并的状态对象,第二个是回调函数
- state是组件内部的状态,props是外界传进来的状态
- 区别 class 有私有数据(this.state) 和 生命周期
- function 只有props,没有私有数据和生命周期
-
npm i -g create-react-app
render(){ let {header,center} = this.state return ( <div className="App"> <Head header={header}/> <Section center={center}/> </div> ); }
- 子接收
let {title,img,content} = props.header let {center} = this.props
- 点击事件,切换class样式,tab切换
<p> { center.map((item,index) => <span onClick={()=>{ this.setState({ ind:index }) }} className={index == ind ? 'active' : ''}>{item.title}</span>) } </p> <p> <img src={center[ind].img} /> <h6>{center[ind].content}</h6> { center[ind].link.map(item => <span>{item}</span>) } </p>
- 子传父
<p onClick={()=>{ this.props.add() }}>123</p>
- 父接收
<Chil add={() => { console.log("add") }}/>
- 点击++
//父组件 class App extends React.Component{ constructor(){ super() this.state = { count:0 } } render(){ let {count}= this.state return <div className="App"> <Chil count={count} add={() => { this.setState({ count:count+1 }) }}/> </div> } } //子组件 class Chil extends React.Component{ constructor(props){ super(props) } render(){ let {count} = this.props return <div> <p>{count}</p> <button onClick={() => { this.props.add() }}>+</button> </div> } }
- 弹框
//父组件 class App extends React.Component { constructor(){ super() this.state = { list:[ { name:"打开alert提示框", title:"提示", mess:"确定执行此操作?", type:"alert" },{ name:"打开confirm提示框", title:"提示", mess:"操作成功", type:"confirm" },{ name:"打开prompt提示框", title:"请输入姓名", type:"prompt" } ], obj:{}, isShow:false } } render(){ let {list} = this.state let {obj,isShow} = this.state return ( <div className="App"> <ul> { list.map((item,key) => <li onClick={() => { this.setState({ //点击谁把谁的数据传过去 obj:item, isShow:true }) }} >{item.name}</li>) } </ul> //弹框,父接收 {isShow ? <Dialog obj={obj} sure={() => { this.setState({ isShow:false }) }}/> : null} </div> ); } } //子组件 class Dialog extends React.Component{ constructor(props){ super(props) } render(){ let {obj} = this.props; return <div className="dialog"> <h5>{obj.title}</h5> <p>{obj.mess ? obj.mess : <input/>}</p> <div> {obj.type !== 'prompt' ? <button>取消</button> : ""} //子传父 <button onClick={() => { this.props.sure() }}>确定</button> </div> </div> } }
- 旧生命周期,描述组件一系列的生长过程,分3个周期(出生,成长,死亡) 创建阶段(出生) constructor(){} 初始化函数,接收props,设置组件的默认状态(state),执行一次
- componentWillMount(){} 组件将要被渲染,执行一次,可以修改state
- render (){} 组件正在被渲染,进行diff算法,产生最小化差异
- componentDidMount(){} 组件渲染结束,执行一次,请求数据,第一次获取到真实dom,想要在组件内操作dom
//响应拦截器 import axios from "axios" let request = axios.create() request.interceptors.response.use(function (response) { // 对响应数据做点什么 return response.data; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); export default request //处理数据 import request from "./request" componentDidMount(){ request.get(path).then((res) => { let {data} = res this.setState({data}) }) }
- 变化阶段(成长)------- 存在期包含的方法 props发生变化 componentWillReceiveProps(nextProps,nextState){} props发生变化,监听props,存在期包含
-
shouldComponentUpdate(nextProps,nextState){return true} 组件是否更新?返回true或false,性能优化,存在其包含
-
componentWillUnmount 组件将卸载,清理组件垃圾
-
出生
constructor
return {}
}
用static关键字,静态方法里没有this,必须return 一个对象或是 null,如果返回null,不会更新,如果返回一个对象,会通过serState更新组件。 监听props变化,更新state状态
-
shouldComponentUpdate() {return true}
return {aa:666}
}
Snapshot快照,返回一个null或一个对象,返回值作为componentDidUpdate的第三个参数存在,需要配合DidUpdata一起使用
-
componentWillUnmount(){}
//父组件 this.state = { obj:{ leftList:[{ type:"紧凑型车", rightLift:[ { img:"1.jpg", name:"紧凑型车", price:"82.80-249万" }, { img:"2.jpg", name:"奔驰S级", price:"87.68-200万" } ] },{ type:"小型车", rightLift:[ { img:"1.jpg", name:"小型车", price:"82.80-249万" }, { img:"2.jpg", name:"奔驰S级", price:"87.68-200万" } ] } list:{}, flag:false } render(){ let {leftList} = this.state.obj let {list,flag} = this.state return ( <div className="App"> <ul className="list"> { leftList.map((item,index) => <li key={index} onClick={() => this.setState({ flag:true, list:item }) }>{item.type}</li> ) } </ul> {flag ? <RightList list={list.rightLift}/> : ""} </div> ); } //子组件 render(){ let {list} = this.props return <div className="right"> { list.map((item,index) => <div> <p key={index}>{item.name}</p> <p key={index}>{item.price}</p> </div> ) } </div> }
- DOM ref – findDOMNode 获取dom
//普通元素 ref = "string" this.refs.string this.refs获取的是一个对象 ref = {(name) => { if(name){} }} render就会调用,函数里的参数就是要获取的dom节点,更改状态时,回调函数会触发俩次,第一次dom是null,第二次才是真实的dom //组件 ref = "string" this.refs.string 获取的是组件实例 findDOMNode(this.refs.string) 获取的是组件的整个dom
- unmountComponentAtNode(根节点root) 清空所有的dom
- Event
事件三要素:事件源,事件类型,事件处理函数(事件对象e)
-
DOM0 onclick 只能添加一次,没有兼容
-
DOM2 addEventListener(事件类型,处理函数,false) 多次添加,有兼容 IE ,
默认false冒泡,true捕获 - 捕获和冒泡只影响触发顺序,不影响谁被触发,触发的元素从当前点击的元素往外触发
- 同时有捕获和冒泡,先执行捕获,再执行冒泡
stopPropagation 阻止默认事件
事件对象 是事件处理函数参数里最后一个
合成事件
-
react 事件默认是冒泡,所有合成事件都是加在document上,没有兼容,合成事件的捕获–onClickCapture
原生事件
原生事件和合成事件同时出现先执行原生事件
原生事件里阻止事件冒泡,有可能合成事件就都不执行了
组件卸载的时候,清空事件,定时器……
用箭头函数,可以获取this <h1 onClick={this.thisClick}>打印this</h1> thisClick () { console.log(this) //undefined } <h1 onClick={this.thisClick}>打印this</h1> thisClick = () => { console.log(this) //This {props: {…}, context: {…}, refs: {…}, updater: {…}, thisClick: ƒ, …} } bind改变this指向 <h1 onClick={this.thisClick.bind(this)}>打印this</h1> thisClick () { console.log(this) //This {props: {…}, context: {…}, refs: {…}, updater: {…}, _reactInternalFiber: FiberNode, …} } constructor周期方法只执行一次,可以优化性能 constructor(){ super() this.thisClick = this.thisClick.bind(this) } render(){ return <div> <h1 onClick={this.thisClick}>打印this</h1> </div> } thisClick () { console.log(this) }
- this指向
//改变this指向后,不会立马触发函数 bind //改变this指向后,会立马触发函数 call 参数是一个一个的 apply 参数是数组
- 定义默认的props
static defaultProps = {} Name.defaultProps = {}
- 拖拽
原理:盒子的距离 = 最后手指到页面距离 - (开始手指到页面距离 - 盒子到页面距离) - 侧边栏
相关文章推荐
- react native关于 从react中引入PropTypes报错的问题
- React native layout整理
- ReactNative学习笔记--下拉选择菜单的简单封装
- 基于react16 webpack3 搭建前端spa基础框架 react-router的4种异步加载方式
- React Native入门学习笔记一(环境搭建windows+android)
- React Native原生模块向JS传递数据的几种方式(Android)
- React Native学习过程1--搭建开发环境
- React Native入门学习笔记三(JSX语法)
- Redux 入门教程(三):React-Redux 的用法
- React Native入门(十四)之动画(1)Animated详解
- ReactJS学习系列课程(props 组件属性)
- 添加react到已存在的项目中(Adding React to an Existing Application)-1
- react的componentWillReceiveProps(nextProps) {} 生命周期
- ReactJS学习系列课程(React 动画使用)
- React Native中的图片缓存详解(二)
- ReactNative开发工具有这一篇足矣
- reactjs学习笔记2--组件的介绍
- React学习之高级ReactDOMServer(二十五)
- react native FlatList使用详解以及上拉刷新下拉加载带可运行demo
- 关于React “Cannot read property 'setState' of null” 的错误