React全家桶

全家桶


1.React介绍


React起源与发展


React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决

定自己写一套,用来架设Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源

了。

为什么要学习React


传统的JavaScript或者之前学习的jquery 操纵DOM 非常的繁琐(编码麻烦),并且效率低下(因为只要我们操纵DOM 那么浏览器就会频繁的对页面进行绘制与排列 )

document.getElementById("xxxx");

document.getElementsByClassName("xxx");

document.getElementsByTagName("xxxx");

$(".xxx")

$("#xxx")

...

...

传统的JavaScript操纵DOM 浏览器会进行大量的重绘重排

传统的JavaScript没有组件化编码方案,代码复用性非常低

React是什么?


官方: React是一个用于构建用户界面的javascript库

react是一个将数据渲染为HTML的开源javascript库

React的特性


1.采用组件化模式 声明式编码 提高开发效率以及组件化复用性

2.在ReactNative中可以使用React语法进行移动端开发

3.使用虚拟DOM+diff算法尽量减少与真实DOM的交互

虚拟Dom--VirtualDom与diff算法

传统的dom操纵会在数据改变的时候 重新把页面的所有内容都绘制一遍 (哪怕是10000条数据 之多了一条 那么他也会重新渲染10001次)

虚拟dom--快减少更新次数 减少更新区域 提高性能

虚拟dom相当于在js和真实dom中间加了一个缓存。基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都首先重新构建整个DOM树(减少页面更新次数),然后React将当前整个DOM树和上一次的DOM树进行对比(DOM Diff算法-计算出虚拟DOM中真正变化的部分),得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。

React与传统MVC的关系


轻量级的视图层库!

React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开

发模式;React 构建页面 UI 的库。可以简单地理解为,React 将界面分成了各个独立的小块,每一个块

就是组件,这些组件之间可以组合、嵌套,就成了我们的页面。

2.HelloWord16.8版本


16.8是react的一个分水岭 其中有很多新增特性 在企业中使用中使用

跟多高版本的特性在后面会慢慢学到

1.获取依赖包

(1)react.js文件是创建React元素和组件的核心文件

(2)react-dom.js文件用来把React组件渲染为DOM,此文件依赖于react.js文件,需在其后被引入。

(3)Babel的主要用途是将ES6转成ES5 同时可以把JSX 语法转换新标准的JavaScript代码让现今浏览器兼容的代码

2.编写代码

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<!-- 1.引用react核心库文件 -->

<scriptsrc="react.16.8.6.js"></script>

<!-- 2.引用react支持dom操作的react-dom -->

<scriptsrc="react-dom.16.8.6.js"></script>

<!-- 3.引用babel -->

<scriptsrc="babel.min.js"></script>

</head>

<body>

<!-- 4.创建一个容器 用来容纳后续渲染内容 -->

<divid="demoDiv"></div>

<scripttype="text/babel">/* 5.此处不要错了 让babel解析其中的内容*/

// 6.创建虚拟dom

let VDom= <h1>你好么么哒!!!</h1>

// 7.把创建的虚拟dom渲染到页面上

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

思考


虽然react 官方推荐我们使用jsx的方式来创建虚拟dom 但是有同学就会好奇 为什么官方要推荐使用jsx来创建虚拟dom

3.VirtualDom的两种创建方式


我们要完成如下图的页面dom

方式1 使用jsx来创建虚拟DOM


其实jsx的方式创建虚拟dom我们刚才在写helloword的时候已经使用过了 我们只需要稍加改造就行了

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

//使用()代表是个整体 直接添加id 与 内容

let VDom=(

<h1 id="xixi">

<span>你坏</span>

</h1>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

方式2 使用原生js来创建虚拟DOM


原生js中使用 document.createElement()来新建dom节点

在我们引用React之后 可以使用React.createElement(标签名,标签属性,标签内容)来创建虚拟dom

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<!-- 由于使用原生 那么就不需要babel了 -->

<!-- <script src="babel.min.js"></script> -->

</head>

<body>

<divid="demoDiv"></div>

<!-- 由于使用原生那么就不用babel -->

<scripttype="text/javascript">

// let VDom=React.createElement(标签名,{标签属性},标签内容)

letVDom=React.createElement("h1",{id:"xixi"},React.createElement("span",{},"你好"))

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

总结

jsx出现的原因 就是因为 传统方式创建虚拟DOM太麻烦了 所以才需要JSX来创建虚拟DOM简化创建虚拟DOM的复杂度(也可以理解为jsx就是传统dom操作的语法糖--语法糖也叫糖衣语法就是用简单的语法完成之前复杂的事情

4.虚拟DOM与真实DOM区别


我们查看下虚拟dom与真实dom到底是什么?

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

let VDom=(

<h1 id="xixi">

<span>你坏</span>

</h1>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

console.log("虚拟dom",VDom);

console.log("真实dom",document.getElementById("demoDiv"));

</script>

</body>

</html>

大家会发现浏览器中显示 虚拟dom就是一个我们常见的普通对象

但是虚拟dom和真实dom里面是什么呢?

我们使用debugger看一下

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

let VDom=(

<h1 id="xixi">

<span>你坏</span>

</h1>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

let ZDom=document.getElementById("demoDiv")

console.log("虚拟dom",VDom);

console.log("真实dom",ZDom);

// 设置断点

debugger

</script>

</body>

</html>

在浏览器中查看会发现

虚拟dom

真实dom

对比后会发现

虚拟dom会比较 而真实dom 比较 因为虚拟dom只需要在react内部在使用需要使用那么多属性

总结


1.虚拟dom就是一个我们常见的普通对象

2.虚拟dom会比较 而真实dom 比较 因为虚拟dom只需要在react内部在使用需要使用那么多属性

3.虚拟dom最终会被react转换成真实dom 展现在页面上

5.jsx语法规则


jsx=javascript xml (xml是一种早起存储数据的格式 是一种要求语法非常严谨的数据格式--现在都使用json)

jsx对语法的要求非常的严格 严格到变态

一个根标签


多行标签需要有一个容器进行包裹

语法严谨


标签必须闭合 必须按照w3c规范来编写

Jsx变量 属性插值 与 注释


定义虚拟dom的时候不加双引号 同时jsx遇见{} 会当js表达式解析 遇见<>当html解析

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

let text="xixi";

let demotext="你好"

let VDom=(

<h1 id={text}>

{/*插入变量*/}

<span>{demotext}</span>

</h1>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

总结:

插入变量: 因为在jsx中遇见{}就会把里面的东西当成js表达式 解析 所以如果我们想插入变量 就把这个变量放到{我是变量}

插入属性: 因为在jsx中遇见{}就会把里面的东西当成js表达式 解析 所以我们如果想给属性插入变量 就把这个变量直接放到 属性={变量}

插入注释:因为在jsx中遇见{}就会把里面的东西当成js表达式 解析 所以我们注释 {/* 我是注释 */}

样式


行内样式

行内样式需要写入一个样式对象

注意语法 第一个{}是jsx的语法 第二个{}是对象的语法

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

let text="xixi";

let demotext="你好"

let VDom=(

<h1id={text}>

<spanstyle={ {color:"red",backgroundColor:"yellow"}}>{demotext}</span>

</h1>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

类样式

jsx中类名不能使用class来设置(因为class是js的关键字)使用className来设置

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

<style>

.demo{

color:red;

background-color: yellow;

}

</style>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

let text="xixi";

let demotext="你好"

let VDom=(

<h1 id={text}>

<span className="demo">{demotext}</span>

</h1>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

数据遍历


在日常工作中我们进场需要把数据进行遍历展示到页面中 那么在jsx中怎么遍历呢?

特殊情况(工作不会遇见)

如果数据是一个数组 那么react会自动把这个数据中的内容遍历出来并且展示

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

let arr=["EZ","VN","MF","NOC"]

let arrb=[<li>EZ</li>,<li>VN</li>,<li>MF</li>,<li>NOC</li>]

let VDom=(

<div>

<ul>

{/*

大家会发现ract会把我们的数据进行遍历

但是这样也有问题就是 ul中不会自动生产标签

*/}

{arr}

</ul>

<ul>

{/*

虽然这样可以遍历出来数据 但是工作中 没有那个后端会给我们返回arrb这 样的数据 所以这种方式行不通

*/}

{arrb}

</ul>

</div>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

那么怎么办呢?

遍历数据

首先我们在遍历数据的时候可以使用 数组的map方法 因为map方法可以遍历数据并且返回出新的内容

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

let arr=["EZ","VN","MF","NOC"]

let VDom=(

<div>

<ul>

{

arr.map((v,i)=>{

return (

<likey={i}>{v}</li>

)

})

}

</ul>

</div>

)

ReactDOM.render(VDom,document.getElementById("demoDiv"))

</script>

</body>

</html>

注意


在jsx中 一对大括号中 放的是js表达式

表达式:通过计算可以返回结果的公式 所以上面的map就是一个表达式 因为map可以返回一个新的结果

但是注意 jsx大括号中不能放置 if switch for 这些js语句 因为他们只是控制程序的执行顺序 不能返回新的结果 所以他们不是表达式

但是注意 jsx大括号中不能放置 if switch for 这些js语句 因为他们只是控制程序的执行顺序 不能返回新的结果 所以他们不是表达式

但是注意 jsx大括号中不能放置 if switch for 这些js语句 因为他们只是控制程序的执行顺序 不能返回新的结果 所以他们不是表达式

6 面向组件编程


组件与组件化 模块与模块化


模块与模块化

模块:用来封装可以重复使用的js代码块

模块化:整个项目都是使用模块的方式来完成的

组件与组件化

组件: 用来封装重复使用的ui代码块

组件化:整个项目都是使用组件的方式来完成的

组件的概念


组件就是把ui部分拆分成一个个独立的并且可以重复使用的部件 在吧这些部件拼装在一起 形成一个页面

组件的设计目的是提高代码复用率,降低测试难度和代码的复杂程度。

1 .提高代码复用率:组件将数据和逻辑进行封装。2 .降低测试难度:组件高内聚低耦合(各个元素高集成度低关联性),很容易对单个组件进行测试。3 .代码的复杂程度:直观的语法,可以极大提高可读性。

React Dev Tools


注意:React Dev Tools是谷歌浏览器的插件 所以别的浏览器不行

在开发原生js的时候,我们经常使用浏览器自带的开发者工具,它足以帮助我们查看和调试js中变量的各种信息。

对于react框架来说,因为它是采用动态渲染生成的代码结构,因此,我们需要一种可以分析react代码结构和变量状态的工具,而react dev tools 就是这样的工具

安装

安装方式1

如果你有科学上网工具 直接可以在谷歌浏览器商店中搜索下载

安装方式2

打开谷歌浏览器--》右上角三个点--》更多工具--》扩展程序--》最最最最关键的一步就是在右上角有个开发者模式的选项打开--》选择左侧上方加载已经解压的扩展程序--》找到对应提供的文件路径即可

设置快捷使用

如果想设置快捷使用

第一步

第二步

默认是灰色的 只要你访问的页面是由react写的 那么他就会显示正常

组件分类


函数组件/无状态组件/工厂组件

函数式组件的基本意义就是,组件实际上是一个函数 这个函数返回一段jsx

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

// 首字母大写

// 首字母大写

// 首字母大写

// 首字母大写

function Fun(){

return (

<div>

<h1>我是一个函数组件</h1>

</div>

)

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

调试

使用刚才安装的调试工具查看

类组件

类组件,顾名思义,也就是通过使用ES6类的编写形式去编写组件,该类必须集成React.Component 其中有一个render的渲染方法 里面有段jsx

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<script src="react.16.8.6.js"></script>

<script src="react-dom.16.8.6.js"></script>

<script src="babel.min.js"></script>

</head>

<body>

<div id="demoDiv"></div>

<script type="text/babel">

class Fun extends React.Component{

render(){

return (

<div>

<h1>我是一个类组件</h1>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

区别

函数组件的创建形式使代码的可读性更好,并且减少了大量冗余的代码,大大的增强了编写一个组件的便利

函数组件不会被实例化,整体渲染性能得到提升,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。

函数组件由于没有实例化过程,所以无法访问组件this中的对象,若想访问this就不能使用这种形式来创建组件

函数组件无法访问生命周期的方法

思考


既然上面说了 函数组件没有this 而类组件中有this 那么类组件中的这个this里面有什么?

7 属性1-state 组件状态(数据/变量)


state状态机

大家发现上图中有state这个属性

state属性:

  1. state 是组件对象最重要的属性,值是对象(可以包含多个 key-value 的组合)

  1. 组件被称为“状态机”(状态机制),通过更新组件的 state 来更新对应的页面显示(重新渲染组件)

1.初始化state 读取

默认情况下 state中是null 我们需要在类组件中初始化 所以我们可以放到 comstructor中进行初始化操作

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<script src="react.16.8.6.js"></script>

<script src="react-dom.16.8.6.js"></script>

<script src="babel.min.js"></script>

</head>

<body>

<div id="demoDiv"></div>

<script type="text/babel">

class Fun extends React.Component{

// 初始化

constructor(props){

super(props)

// 1.设置state

this.state={

bool:true

}

}

render(){

return (

<div>

{/*2.使用state状态*/}

<h1>我是一个类组件--{this.state.bool?"你好":"你坏"}</h1>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

2.修改state

更新状态需要调用 this.setState() 方法

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<script src="react.16.8.6.js"></script>

<script src="react-dom.16.8.6.js"></script>

<script src="babel.min.js"></script>

</head>

<body>

<div id="demoDiv"></div>

<script type="text/babel">

class Fun extends React.Component{

constructor(props){

super(props)

this.state={

bool:true

}

}

fun=()=>{

// 修改需要使用setState

this.setState({

bool:!this.state.bool

})

}

render(){

return (

<div>

<h1 onClick={this.fun}>我是一个类组件--{this.state.bool?"你好":"你坏"}</h1>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

setState调用后发生了什么


setState是异步的

(如果有大量数据修改的话不会因为修改数据而造成程序的卡顿)

importReact, { Component } from'react'

exportdefaultclassdemobextendsComponent {

// 初始化state状态数据需要放到constructor中进行初始化

// es6中继承的规则中得知 子类是可以不写constructor 他会在实例化的时候

// 自动补充一个

// 但是如果你写了 那么必须在其中写super() 因为super就是调用父类的构造方法

// 此时子类才有this

constructor() {

super()

// 初始化state

this.state={

text:"我是字符串",

num:888,

bool:true,

arr:[1111,2222,333],

obj:{

name:"xixi"

}

}

}

fun=()=>{

// 修改state的数据

// this.setState({

// num:123,

// text:"xixi"

// })

// 下面的console.log打印的结果是修改之后的 还是修改之前的?

// 是修改之前的结果 所以从而证明了setState是一个异步任务

// console.log(this.state.num)

// 但是我就是想setState修改完数据之后 打印新的结果怎么办?

// 因为setState是异步 异步都会有回调函数

this.setState({

num:123,

text:"xixi"

},()=>{

// setState第二个参数是一个回调函数 当数据修改完他才会调用

console.log(this.state.num)

})

}

render() {

return (

<>

{/* 2.使用state数据 */}

<h1>我是测试state使用的例子----{this.state.num}---{this.state.text}</h1>

<buttononClick={this.fun}>点我修改</button>

</>

)

}

}

调用了setState之后会自动触发render渲染

render就是渲染方法 只有render方法执行了 那么页面才会根据数据的改变而随之发生改变

render就是渲染方法 只有render方法执行了 那么页面才会根据数据的改变而随之发生改变

render就是渲染方法 只有render方法执行了 那么页面才会根据数据的改变而随之发生改变

render就是渲染方法 只有render方法执行了 那么页面才会根据数据的改变而随之发生改变

state的简写写法


因为类中可以直接编写赋值语句所以我们的state也可以直接创建 简化了写法

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

class Fun extends React.Component{

// 创建state

state={

bool:true

}

fun=()=>{

// 修改需要使用setState

this.setState({

bool:!this.state.bool

})

}

render(){

return (

<div>

<h1onClick={this.fun}>我是一个类组件--{this.state.bool?"你好":"你坏"}</h1>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

hook-useState


useState

useState 是reactHOOK给我们提供的 最基本最常用的一个HOOK 主要作用就是用来管理当前本地的状态

useState() 返回值是一个数组(长度为2)数组的第一项标识的是当前的值 数组的第二项标识的时候修改这个值的函数

let [xiaoming , setXiaoming]=useState(初始值)

创建与读取

import {useState} from "react"

let Funcom=()=>{

// 使用useState()c创建函数组件的状态

let [xiaoming,setxiaoming]=useState("你好么么哒!!!")

return (

<div>

{/* 读取 */}

<h1>我是一个函数组件--{xiaoming}</h1>

</div>

)

}

export default Funcom

修改

import {useState} from "react"

let Funcom=()=>{

// 使用useState()创建函数组件的状态

let [xiaoming,setxiaoming]=useState("你好么么哒!!!")

return (

<div>

{/* 读取 */}

<h1>我是一个函数组件--{xiaoming}</h1>

{/* 修改数据 */}

<button onClick={()=>{setxiaoming(xiaoming="你好呵呵哒")}}>点我修改</button>

</div>

)

}

export default Funcom

创建多个状态呢

1.你写多个useState

import {useState} from"react"

letFuncom=()=>{

// 1.你写多个useState了解

let [xiaoming,setxiaoming]=useState("1")

let [xiaohong,setxiaohong]=useState("2")

return (

<div>

{xiaoming}---{xiaohong}

</div>

)

}

exportdefaultFuncom

2.一次行创建多个值

import {useState} from"react"

letFuncom=()=>{

// 1.你写多个useState了解

// let [xiaoming,setxiaoming]=useState("1")

// let [xiaohong,setxiaohong]=useState("2")

// 2.一次性创建多个值

let [xiaoming,setxiaoming]=useState({

dataa:"第一个值1",

datab:"第一个值2",

datac:"第一个值3",

datad:"第一个值4",

datae:"第一个值5",

dataf:"第一个值6"

})

return (

<div>

{/* {xiaoming}---{xiaohong} */}

{xiaoming.dataa}----{xiaoming.datad}

</div>

)

}

exportdefaultFuncom

一次性创建多个值怎么修改

1.多个useState 要修改的话就依次调用其中的修改方法

2.一次行创建多个值的方式如何修改呢

import {useState} from "react"

let Funcom=()=>{

// 1.你写多个useState了解

// let [xiaoming,setxiaoming]=useState("1")

// let [xiaohong,setxiaohong]=useState("2")

// 2.一次性创建多个值

let [xiaoming,setxiaoming]=useState({

dataa:"第一个值1",

datab:"第一个值2",

datac:"第一个值3",

datad:"第一个值4",

datae:"第一个值5",

dataf:"第一个值6"

})

let fun=()=>{

// 一次性创建多个的修改操作 不要忘了保留原始数据

setxiaoming({...xiaoming,datad:"我被改了"})

}

return (

<div>

{/* {xiaoming}---{xiaohong} */}

{xiaoming.dataa}----{xiaoming.datad}

<button onClick={fun}>点我修改</button>

</div>

)

}

export default Funcom

总结state


state就是react中用来创建状态的 状态就是数据

在我们使用state的时候有两种情况 分别是函数组件和类组件

类组件 中使用state来进行状态的创建 在修改的时候必须调用setState来进行修改 因为setState是异步的 并且会自动触发render重新渲染 从而让状态数据改变之后 页面也跟着改变

函数组件:他有另外一个名字叫无状态组件 也就是说默认情况不能使用state状态 如果要使用 我们可以使用react16.8新增的一个特性叫HOOK中的useState来进行状态的创建 useState接收一个参数 并且返回数组长度为2的一个内容 第一个是保存的变量 第二个是修改的动作

8 事件


在react中事件的绑定 使用小驼峰命名法

例:onclick 在react中 onClick onchange 在react中 onChange

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了

基本事件操纵


事件绑定 使用小驼峰命名法 鼠标左键点击事件 onclick------》onClick onchange------》onChange

修改this指向


想想函数中的this指向

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<script src="react.16.8.6.js"></script>

<script src="react-dom.16.8.6.js"></script>

<script src="babel.min.js"></script>

</head>

<body>

<div id="demoDiv"></div>

<script type="text/babel">

class Fun extends React.Component{

fun(){

console.log(this)//undefined

}

render(){

return (

<div>

<button onClick={this.fun}>点我</button>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

this是 undefined 所以我们在使用setState等属性方法的时候就会报错

怎么解决呢?

方式1 bind()

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<script src="react.16.8.6.js"></script>

<script src="react-dom.16.8.6.js"></script>

<script src="babel.min.js"></script>

</head>

<body>

<div id="demoDiv"></div>

<script type="text/babel">

class Fun extends React.Component{

fun(){

console.log(this)

}

render(){

return (

<div>

{/*bind方式修改this*/}

<button onClick={this.fun.bind(this)}>点我</button>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

方式2 通过创建箭头函数

在创建函数的时候创建一个箭头函数

方式3 在constructor中提前对事件进行绑定

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

class Fun extends React.Component{

constructor(props){

super(props)

// 提前绑定this

this.fun=this.fun.bind(this)

}

fun(){

console.log(this)

}

render(){

return (

<div>

<buttononClick={this.fun}>点我</button>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

方式4 将事件调用的写法改为箭头函数的形式

<!DOCTYPE html>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metahttp-equiv="X-UA-Compatible"content="IE=edge">

<metaname="viewport"content="width=device-width, initial-scale=1.0">

<title>Document</title>

<scriptsrc="react.16.8.6.js"></script>

<scriptsrc="react-dom.16.8.6.js"></script>

<scriptsrc="babel.min.js"></script>

</head>

<body>

<divid="demoDiv"></div>

<scripttype="text/babel">

class Fun extends React.Component{

fun(){

console.log(this)

}

render(){

return (

<div>

{/*使用箭头函数调用*/}

<buttononClick={()=>{this.fun()}}>点我</button>

</div>

)

}

}

ReactDOM.render(<Fun/>,document.getElementById("demoDiv"))

</script>

</body>

</html>

函数参数传递


因为在react中函数调用的时候不加() 那我我们如果要传递函数的实参怎么传递?

方式1

使用bind方式进行传递

<button onClick={this.fun.bind(this,"我是实参1","我是实参2")}>点我传递函数实参</button>

方式2

使用箭头函数调用函数进行传递

<button onClick={()=>{this.funb(1111,2222)}}>点我传递实参2</button>

事件对象event


使用event

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<script src="react.16.8.6.js"></script>

<script src="react-dom.16.8.6.js"></script>

<script src="babel.min.js"></script>

</head>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值