1.React介绍
多行html 空标签
在react的组件中多行html必须有一个父容器包裹 所以通常我们使用div来进行包裹 但是有的时候这些div是多余的 会在页面生成很多无用的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React from 'react' import ReactDOM from 'react-dom'
class Demob extends React.Component { render() { return ( <div> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> </div> ) } }
ReactDOM.render( <Demob></Demob>, document.getElementById('root') )
|
空标签
空标签 在页面是不进行展示的 它的作用仅仅就是用来描述多行标签的一个包裹作用
写法1:
<></>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React from 'react' import ReactDOM from 'react-dom'
class Demob extends React.Component { render() { return ( <> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> </> ) } }
ReactDOM.render( <Demob></Demob>, document.getElementById('root') )
|
写法2:
Fragment空标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React from 'react' import ReactDOM from 'react-dom'
class Demob extends React.Component { render() { return ( <React.Fragment> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> <h1>你好我是一个标签</h1> </React.Fragment>
) } }
ReactDOM.render( <Demob></Demob>, document.getElementById('root') )
|
动态属性
属性插入变量使用:属性={属性值}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React from 'react' import ReactDOM from 'react-dom'
class Demob extends React.Component { render() { let text="点我去百度" let ahref="http://www.baidu.com" return ( <> <h1>属性插变量</h1> {/* react中属性插变量 属性={你要插的值} */} <a href={ahref}>{text}</a> </> ) } }
ReactDOM.render( <Demob></Demob>, document.getElementById('root') )
|
事件处理
在react中事件的绑定 使用小驼峰命名法
例:onclick 在react中 onClick onchange 在react中 onChange
绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了
绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了
绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了
绑定完事件之后在调用函数的时候不加()不加() 因为加了函数就自动调用了
基本事件操纵
事件绑定 使用小驼峰命名法 鼠标左键点击事件 onclick——》onClick onchange——》onChange
类组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React from 'react' import ReactDOM from 'react-dom'
class Demob extends React.Component { fun=()=>{ console.log("你好") } render() { return ( <> {/* 函数注意 */} <button onClick={this.fun}>点我触发函数</button> </> ) } }
ReactDOM.render( <Demob></Demob>, document.getElementById('root') )
|
函数组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React from 'react' import ReactDOM from 'react-dom' let demo=()=>{ console.log("事件") }
let Fun=()=>{
return ( <div> <h1>我是一个函数组件</h1> <button onClick={demo}>点我调用事件</button> </div> ) }
ReactDOM.render( <Fun></Fun>, document.getElementById('root') )
|
函数参数传递
因为在react中函数调用的时候不加() 那我我们如果要传递函数的实参怎么传递?
1.使用bind方式进行传递
函数组件
1
| <button onClick={fun.bind(this,"你好我是实参")}>点我</button>
|
类组件
1
| <button onClick={this.fun.bind(this,"我是实参1","我是实参2")}>点我传递函数实参</button>
|
2.使用箭头函数调用函数进行传递
函数组件
1
| <button onClick={()=>{fun("我是参数")}}>点我</button>
|
类组件
1
| <button onClick={()=>{this.funb(1111,2222)}}>点我传递实参2</button>
|
阻止事件传播与默认行为
同原生js
事件对象
使用event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React, { Component,Fragment } from 'react'
export default class Com extends Component { fun=(event)=>{ console.log("您在输入框中是",event.target.value) } render() { return ( <Fragment>
<h1>事件对象</h1> <input type="text" onInput={this.fun}/> </Fragment> ) } }
|
遍历展示
react推荐使用map方法来进行数据的便利
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import React, { Component } from 'react' let arr = [111, 222, 333, 444, 555, 666, 777]; export default class democ extends Component { render() { return ( <React.Fragment> <h1>便利数据</h1> <ul>
{ arr.map((v,i)=>{ return ( <li key={i}>{v}</li> ) }) } </ul>
</React.Fragment> ) } }
|
遍历复杂数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import React, { Component } from 'react' let arr = [111, 222, 333, 444, 555, 666, 777]; let obj=[ {name:"xix1i",age:181}, {name:"xix2i",age:182}, {name:"xix3i",age:183}, {name:"xix4i",age:184}, {name:"xix5i",age:185}, {name:"xix6i",age:186} ] export default class democ extends Component { render() { return ( <React.Fragment> <h1>便利数据</h1> <ul>
{ arr.map((v,i)=>{ return ( <li key={i}>{v}</li> ) }) } </ul>
<hr />
<table border="1"> <tbody> { obj.map((v,i)=>{ return ( <tr key={i}> <td>{v.name}</td> <td>{v.age}</td> </tr> ) }) } </tbody> </table>
</React.Fragment> ) } }
|
ref
函数组件 无状态组件 不能使用ref
ref 标识组件内部的元素 就给组件的dom元素起个名字
函数组件是不能直接使用ref的
ref写法的分类
1.字符串(官方已经不推荐使用了)
2.回调函数(官方推荐方式)
回调函数的方式 就是在dom节点上挂载一个函数 函数的入参 就是dom节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import React from 'react' import ReactDOM from 'react-dom'
class Demob extends React.Component { fun=()=>{ console.log(this.demoinput.value) } render() { return ( <div> <h1>ref的例子</h1> {/* 回调函数的方式创建ref */} {/* <input type="text" ref={(text这个变量代表的就是当前这个input标签)=>{this.demoinput(随便创建一个变量)=text}}/> */} <input type="text" ref={(text)=>{this.demoinput=text}}/> <button onClick={this.fun}>点我得到输入框的值</button> </div> ) } }
ReactDOM.render( <Demob></Demob>, document.getElementById('root') )
|
3.React.createRef()(16.8版本新增的 官方推荐)
react 16.8新增的一种方式 我们通过初始化createRef从而得到ref对象 插入到页面中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import React from 'react' import ReactDOM from 'react-dom'
class Demob extends React.Component { inputref=React.createRef() fun=()=>{ console.log(this.inputref.current.value) } render() { return ( <div> <h1>createRef</h1> {/* 2.绑定 */} <input type="text" ref={this.inputref}/> <button onClick={this.fun}>点我得到输入框的值</button> </div> ) } }
ReactDOM.render( <Demob></Demob>, document.getElementById('root') )
|
扩展–插入字符串标签
在vue中插入字符串标签使用v-html这个指令即可完成
在今后实际工作的时候 会出现后台给你返回的就是一大段生成好的html 你需要把他展示在页面上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import React, { Component } from 'react'
export default class demod extends Component { state={ newhtml:"<h1>我是h1我是一段字符串标签</h1>" } render() { return ( <div> demod {/* 插入字符串标签 */} <div dangerouslySetInnerHTML={{__html:this.state.newhtml}}> </div> </div> ) } }
|
条件渲染
在开发中 创建不同的组件来封装我们需要完成的各个内容 但是我们需要根据程序的状态变化来渲染其中一部分内容
if语句来看进行条件渲染
在react中if条件渲染是最简单的 但是但是但是但是 注意 在jsx不允许出现if
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React, { Component } from 'react'
export default class demo extends Component { render() { let newhtml="" let num=1
if(num==1){ newhtml= <h1>吃饭</h1> }else if(num==2){ newhtml= <h1>睡觉</h1> }else{ newhtml=<h1>打豆豆</h1> } return ( <div> {newhtml} </div> ) } }
|
三元运算符
使用图片
1.把图片放到public文件夹中 直接使用图片名
2.不在public下 我们可以使用require()来进行引用
1
| <img src={require("../assets/2.webp")} />
|
3.不在public下 我们也可以使用导入式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React, { Component } from 'react'
import imgA from "../assets/2.webp" export default class demob extends Component { render() { return ( <div> {/* <img src="img/1.webp" /> */}
{/* <img src={require("../assets/2.webp")} /> */}
{/* 2.使用 */} <img src={imgA} /> </div> ) } }
|
5 组件的数据挂载方式
状态state
状态(变量/数据)机制 在react中我们只需要把数据定义在state中 那么数据改变了页面也会发生改变
通过状态就可以让页面内容在不操作dom的情况下 进行相应式的改变
函数组件也叫无状态组件 所以函数组件中不能使用状态 (react16.8新增了一个叫HOOK的技术可以实现)
函数组件也叫无状态组件 所以函数组件中不能使用状态
使用
1.定义状态数据方式1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import React, { Component } from 'react'
export default class demob extends Component {
constructor() { super() this.state={ text:"我是字符串", num:888, bool:true, arr:[1111,2222,333], obj:{ name:"xiaoyang" } } } render() { return ( <> <h1>我是测试state使用的例子</h1> </> ) } }
|
定义状态数据方式2
这种方式也是没有问题的 而且简单 但是 你去公司了 你看看你同事这样子写没有 如果没有 你就不要用了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React, { Component } from 'react'
export default class demob extends Component {
state={ text:"我是字符串", num:888, bool:true, arr:[1111,2222,333], obj:{ name:"xiaoyang" } } render() { return ( <> <h1>我是测试state使用的例子</h1> </> ) } }
|
2.使用state数据
this.state 是纯js对象,在vue中,data属性是利用 Object.defineProperty 处理过的,更改data的数据的时候会触发数据的 getter 和 setter ,但是React中没有做这样的处理,如果直接更改的话,react是无法得知的,所以,需要使用特殊的更改状态的方法 setState 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import React, { Component } from 'react'
export default class demob extends Component {
constructor() { super() this.state={ text:"我是字符串", num:888, bool:true, arr:[1111,2222,333], obj:{ name:"xiaoyang" } } } render() { return ( <> {/* 2.使用state数据 */} <h1>我是测试state使用的例子----{this.state.num}</h1>
</> ) } }
|
3.修改state的数据
this.setState({你修改谁:修改成什么})
修改state的数据必须使用setState修改之后页面才会发生改变
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import React, { Component } from 'react'
export default class demob extends Component {
constructor() { super() this.state={ text:"我是字符串", num:888, bool:true, arr:[1111,2222,333], obj:{ name:"xiaoyang" } } }
fun=()=>{ this.setState({ num:123, text:"xiaoyang" }) }
render() { return ( <> {/* 2.使用state数据 */} <h1>我是测试state使用的例子----{this.state.num}---{this.state.text}</h1> <button onClick={this.fun}>点我修改</button>
</> ) } }
|
调用了setState之后发生了什么?
setState是异步的
(如果有大量数据修改的话不会因为修改数据而造成程序的卡顿)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| import React, { Component } from 'react'
export default class demob extends Component {
constructor() { super() this.state={ text:"我是字符串", num:888, bool:true, arr:[1111,2222,333], obj:{ name:"xiaoyang" } } }
fun=()=>{
this.setState({ num:123, text:"xiaoyang" },()=>{ console.log(this.state.num) }) }
render() { return ( <> {/* 2.使用state数据 */} <h1>我是测试state使用的例子----{this.state.num}---{this.state.text}</h1> <button onClick={this.fun}>点我修改</button> </> ) } }
|
调用了setState之后会自动触发render渲染
render就是渲染方法 只有render方法执行了 那么页面才会根据数据的改变而随之发生改变