当前位置: 首页 > news >正文

React小记(一)_基础部分

1、项目搭建与结构

2、类组件和函数组件

    主要区别:1、函数组件没有生命周期2、函数组件没有this指向3、函数组件没有状态4、函数组件通过hooks实现各种操作5、props在函数的第一个参数接收6、函数体相当于类组件的render函数

import React from 'react'function App() {// 1、函数组件function Fn() {return <div>fn hello</div>}// 2、类组件class ClassHello extends React.Component{// 构造器可有可无constructor(props) {super(props)}// render必须有render() {return <div>class hello</div>}}return (<div className="App"><Fn></Fn><ClassHello></ClassHello></div>);
}export default App;

3、js与jsx语法

    1、jsx和react是相互独立的2、写法相似,更加简便3、可以和js混用4、最终会转化为和一个【React-element对象】5、不借助jsx,可以通过React.createElement创建

3.1 创建DOM的两种方式

    二者最终得到的内容是一致的,均是React的element对象
import React from 'react'function App() {function Fn() {// 1、React 创建Dom写法// React.createElement('标签名',[属性],'内容')return React.createElement('div',[],'hello,fn')}class ClassHe extends React.Component{constructor(props) {super(props)}render() {// 2、jsx 创建Dom写法return <div>hello,class</div>}}return (<div className="App"><Fn></Fn><ClassHe></ClassHe></div>);
}export default App;

3.2 jsx中不同类型数据的渲染.js

    1、字符串/数字 => 直接渲染2、对象(vue中当成字符串渲染)element对象 => 直接渲染 普通对象 => 取到每一项后可以渲染3、数组(普通/元素数组) => 把数组中的每一项进行渲染4、表达式 => 得到运行结果渲染5、方法 => 无法渲染6、布尔值 => 不渲染7、undefined/null => 不渲染
import React from 'react'function App() {// 1、字符串const str = 'good !!!'// 2、数字const num = 123// 3、普通对象const obj = {a:1}// 4、element 对象const eleObj = <span>span</span>// 5、普通数组const arr = [1, 2, 3]// 6、elememt 数组const eleArr = [<p>1111</p>,<p>2222</p>,<p>3333</p>]// 7、表达式// 如果数组的长度为3 则显示对象中的a// 8、方法 无法渲染// 9、布尔值const boll = false// 10、undefined / null;var ss const na = nullreturn (<div className="App"><span> 字符串:</span> {str} <br /><span> 数字:</span>{num} <br /><span>普通对象:</span>{/* 直接取取不到,需要拿到具体的 */}{obj.a} <br /><span>元素对象:</span>{eleObj} <br /><span>普通数组:</span>{arr} <br /><span>元素数组:</span>{eleArr}<span>表达式:</span>{arr.length === 3 ? obj.a : ''} <br /><span>布尔值:</span>{boll} <br /><span>undefined:</span>{ss} <br /><span>null</span>{na} <br /></div>);
}export default App;

4、事件绑定

    1、写法类似原生 on + 方法名(首字母大写)2、给事件赋值为某个方法,但是不要执行 

4.1 方法写在外面

import React from 'react'class App extends React.Component{// 声明函数时 赋值语句 + 箭头函数
handleClick = ()=> {console.log('点击了按钮');
}
render() {return (<button onClick={this.handleClick}>点我触发事件</button>)
}
}export default App;

4.2 方法写在里面

import React from 'react'class App extends React.Component{render() {return (<button onClick={() => {console.log('点击了按钮');}}>点我触发事件</button>)}
}export default App;

4.3 注意事项

【特别注意】1、类组件想要拿到事件处理函数中this要处理 不然会undefined(1) 事件处理函数声明时,声明为【箭头函数+赋值语句】(2) 使用bind改变this指向,在需要传参时多用(3) 内联式写法,函数写为【匿名函数+箭头函数】2、给事件绑定的是一个方法,且不要直接调用
  1. 事件处理函数声明时,声明为【箭头函数+赋值语句】
import React from 'react'class App extends React.Component{// 声明函数时 赋值语句 + 箭头函数
handleClick = ()=> {console.log(this);  // App
}
render() {return (<button onClick={this.handleClick()}>点我触发事件</button>)
}
}export default App;
  1. 使用bind改变this指向,在需要传参时多用
import React from 'react'class App extends React.Component{// 2、使用bind在模板中改变this指向,传参时多用handleClick(a){console.log(this,a);  // App 传参}render() {return (<button onClick={this.handleClick.bind(this,'传参')}>点我触发事件</button>)}
}export default App;
  1. 内联式写法,函数写为【匿名函数+箭头函数】
import React from 'react'class App extends React.Component{// 3、内联 【匿名函数 + 箭头函数】render() {return (<button onClick={() => {console.log(this);  // App}}>点我触发事件</button>)}
}export default App;

4.4 事件绑定其他操作

    1、传递参数 :bind(this,'参数')2、获取事件对象 e3、阻止默认行为、冒泡等
import React from 'react'class App extends React.Component {// 声明函数时 赋值语句 + 箭头函数handleClick = (a,b,e) => {console.log('接收参数', a, b);  // 不传参 第一个参数// 传参 最后一个参数console.log('合成事件对象', e);console.log('原生事件对象', e.nativeEvent);e.stopPropagation();   // 阻止冒泡e.preventDefault();    // 阻止默认行为}render() {return (<button onClick={this.handleClick.bind(this,1,2)}>点我触发事件</button>)}
}
export default App;

5、响应式数据(类组件)

    1、react不能像vue一样【直接修改】触发更新2、react直接修改能修改值,无法触发更新3、react没有像vue的get和set监听,借助【setState】触发更新

5.1 setState的本质

    1、修改数据2、触发更新
    以下两种写法是等价的add = () => {this.setState({a:++this.state.a})}add = () => {this.state.a += 1this.setState({})}

5.2 setState 获取最新值

    1、setState 修改值是异步操作2、获取最新值要在setStete第二个参数【回调函数】中获取
    this.setState({// 在这修改值a:++this.state.a}, () => {// 在这拿到最新的值console.log('拿到a最新的值',this.state.a);})

5.3 setState 细节

    1、setState传递对象,通过浅合并(Object.assign),并非替换2、由于浅合并,深层次的修改需要先赋值一份
import React from 'react'class App extends React.Component {// 1、声明状态state = {a: 0,b: 1,c: {c1: 2,c2: 3}}// 2、修改状态add = () => {this.setState({a: ++this.state.a,c: {// 由于浅合并,深层次的修改需要先赋值一份...this.state.c,c2:4}}, () => {console.log('拿到a最新的值',this.state.a);})}render() {return <div><span>获取状态:</span>{this.state.a} <br /><span>c2的值:</span>{this.state.c.c2} <br /><span>修改状态:</span><button onClick={this.add}>点我修改</button> <br /></div>}
}export default App;

5.4 setState的一些特性

    1、多次修改数据,会合并为一次,最后触发更新2、setState每次调用都会触发更新(无论数据是否修改)借助 PureComponent 优化类组件a、数据不变,组件不刷新b、当修改对象和数组时,要先解除引用,否则不更新3、不要再render中调用setState
// 修改arr [页面不变-因为地址不变]addArr1 = () => {this.state.arr.push(4)this.setState({arr:this.state.arr}, () => {console.log(this.state.arr);})}// 先解除引用 再修改addArr = () => {let arr_ = [...this.state.arr]arr_.push(4)this.setState({arr: arr_}, () => {console.log(this.state.arr);})}

6、条件渲染

    1、利用js编写自定义逻辑2、根据逻辑(true/false)渲染相应的内容3、主要方式(1) 三元表达式(2) && ||(3) if else
import React from 'react'class App extends React.PureComponent {state = {show: true,isHot:true}fn = () => {if (this.state.show) {return <span>if</span>} else {return <span>else</span>}}handleClick = () => {this.setState({show: !this.state.show,isHot:!this.state.isHot})}render() {return <div><h3>条件渲染</h3>{/* 1、三元表达式 */}{this.state.show ? '显示' : '隐藏'} <br />{/* 2、&&  ‘true才执行’ */}{this.state.isHot && '天气很热'} <br />{/* 3、if else */}{this.fn()} <br /><button onClick={this.handleClick}>点我切换</button></div>}
}export default App;

7、列表渲染

    1、使用数组遍历方法 将后端返回的数组中每一项取出来渲染成jsx(1) 拿到原始数据:后端数据(2) 将每一项数据转化为DOM元素(3) jsx 渲染2、常用方法(1) map 有返回值(2) forEach 没有返回值(3) filter 过滤
import React from 'react'class App extends React.PureComponent {state = {arr: [1, 2, 3],eleArr: [<div>1</div>,<div>2</div>,<div>3</div>,]}getArr = () => {let newArr = []this.state.arr.forEach(item => {newArr.push(<p key={item}>{ item}</p>)})return newArr}render() {return <div><h3>列表渲染</h3>{this.state.arr} <br />{this.state.eleArr}<hr />{/* 1、使用map */}{this.state.arr.map(item => (<h3 key={item}>{ item }</h3>))}<hr />{/* 2、使用forEach */}{this.getArr()}</div>}
}export default App;

8、样式操作

    1、class类名设置(1) 必须写成 className(2) 样式单独写在一个css文件中如果不做处理,样式会全局生效(产生样式污染)(3) 只能接受一个字符串 '' {}2、style内联写法不能像原生一样写成字符串'',必须写成对象 {{ }}3、解决样式污染(1) 改名 将 .css => .module.css(2) 将样式文件引入为对象 import sonStyle from ''(3)【sonStyle.son】/【sonStyle['son']】取出类名使用4、动态控制类名引入状态,根据状态使用条件渲染出切换类名(拼接字符串)(1) 手动拼接字符串(少量)(2) 借助 classnames 拼接a、帮助我们生成计算好的类名的字符串

8.1 手动拼接字符串

import React from 'react'
import './App.css'class App extends React.PureComponent {state = {isShow : true}handle = () => {this.setState({isShow:!this.state.isShow})}render() {return (<div className="App">{/* 手动拼接 */}<span className={ this.state.isShow ? 'color' :''}> 动态添加类名</span> <br /><button onClick={this.handle}>点我切换</button></div>)}
}export default App;

8.2 借助 classnames 拼接

import React from 'react'
import classnames from'classnames'
import style from'./App.module.css'class App extends React.PureComponent {state = {isShow : true}handle = () => {this.setState({isShow:!this.state.isShow})}render() {return (<div className={style.App}>{/* 借助classnames拼接 */}<span className={classnames({{/* 不需要改变this指向 */}[style['color']]:this.state.isShow})}> 动态添加类名</span> <br /><button onClick={this.handle}>点我切换</button></div>)}
}export default App;

9、受控组件和非受控组件

  回想原生:1、获取表单的值   onInput={this.handleClick}a、绑定监听事件 input/changeb、通过【e.target.value】获取2、设置表单的值   value={this.state.inputValue}设置value/checke属性
import React from 'react'class App extends React.PureComponent {state = {inputValue:''}handleClick = (e) => {this.setState({inputValue: e.target.value})}change = () => {this.setState({inputValue: 11})}render() {return (<div><input value={this.state.inputValue} onInput={this.handleClick} /><span> {this.state.inputValue}</span> <br /><button onClick={this.change}>变更inputValue</button></div>)}
}export default App;

9.1 受控组件(双向的)

    1、表单的值可以获取【state】,并可以由开发者靠代码【setState】去更改2、可以通过设置state中的值改变表单中的值3、将表单数据添加到state中,可以通过【state/setState】对数据进行获取和修改

9.2 受控组件(无状态的)

    1、表单的值我们只能获取【通过给输入框打标识获取】2、我们仅做了事件监听,没有设置 value/checked 属性3、没有设置 state

9.3 关于复选框

    1、 value  选中后的值2、checked 控制是否选中
http://www.lryc.cn/news/374696.html

相关文章:

  • 40、基于深度学习的线性预测设计(matlab)
  • 【初体验 threejs】【学习】【笔记】hello,正方体 3!
  • 第04章:IDEA的安装与使用
  • [原创][Delphi多线程]使用TMonitor, TEvent和TQueue配合实现TThreadQueue的经典使用案例.
  • 6.12ctf练习
  • 海豚调度异常处理: 使用 arthas 在内存中删除启动失败的工作流
  • 在Qt中,QSerialPort::write(data) 和 readAll() 有什么关联和联系
  • 第 2 章:Spring Framework 中的 IoC 容器
  • 构造函数、实例、原型对象三者之间的关系
  • 人工智能抢走了他们的工作。现在他们得到报酬,让它听起来像人类
  • 大模型微调出错的解决方案(持续更新)
  • 企业多云策略的优势与实施指南
  • vue分页
  • 服务器上设置pnpm环境变量
  • Java中BIO、NIO、AIO详解
  • cloud_enum:一款针对不同平台云环境安全的OSINT工具
  • 图像的对比度和亮度
  • 手撕设计模式——计划生育之单例模式
  • Mac M3 Pro 部署Flink-1.16.3
  • Mysql 的分布式策略
  • 记录一个利用winhex进行图片隐写分离的
  • 压缩映射定理证明
  • Ubuntu20.04.6操作系统安装教程
  • (分治算法3)leecode 53 最大子数组和(最大子段和)
  • 【C++】模板初级
  • eslint 使用单引号,Prettier使用双引号冲突
  • 进化生物学的数学原理 知识点总结
  • 如何挑到高质量的静态IP代理?
  • vagrant putty错误的解决
  • 图像分割——U-Net论文介绍+代码(PyTorch)