1、React组件 1、函数式组件(只能使用props)
2、类式组件(常用)function Demo(){ console.log(this) return函数式组件 } ReactDOM.render(
, document.getElementById('test'))
【#|React组件实例的三大属性】函数式组件使用props属性
//创建组件 function Person (props){ const {name,age,sex} = props return (
) } Person.propTypes = { name:PropTypes.string.isRequired, //限制name必传,且为字符串 sex:PropTypes.string,//限制sex为字符串 age:PropTypes.number,//限制age为数值 }//指定默认标签属性值 Person.defaultProps = { sex:'男',//sex默认值为男 age:18 //age默认值为18 } //渲染组件到页面 ReactDOM.render(,document.getElementById('test1'))
- 姓名:{name}
- 性别:{sex}
- 年龄:{age}
2、三大属性---state 1、基本使用class MyComponent extends React.Component { render(){ console.log('render中的this: ', this) return ( 类式组件 ) } } ReactDOM.render(
, document.getElementById('test'))
render中的this是组件实例对象
文章图片
//1.创建类式组件 class MyComponent extends React.Component { render(){ //render是放在哪里的?—— MyComponent的原型对象上,供实例使用。 //render中的this是谁?—— MyComponent的实例对象 <=> MyComponent组件实例对象。 console.log('render中的this:',this); return 我是用类定义的组件(适用于【复杂组件】的定义) } } //2.渲染组件到页面 ReactDOM.render(
,document.getElementById('test')) /* 执行了ReactDOM.render( .......之后,发生了什么? 1.React解析组件标签,找到了MyComponent组件。 2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。 3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。 */
主要用于给组件this.state赋内部变量,这个变量可以通过模板字符串显示在render渲染的组件中2、响应式修改state
使用构造器constructor的时候,第一句必须是super(props)
下面的例子中changeWeather是原型上的function,所以再按钮中的onClick事件赋值的时候会造成changeWeater的this丢失
- 有一种方法是再构造器中对实例声明一个Weather函数,把原型上的方法绑定实例this赋值给这个函数,如下
//1.创建组件 class Weather extends React.Component{ //构造器调用几次? ———— 1次 constructor(props){ super(props) //初始化状态 this.state = {isHot:false,wind:'微风'} //解决changeWeather中this指向问题 this.changeWeather = this.changeWeather.bind(this) } //render调用几次? ———— 1+n次 1是初始化的那次 n是状态更新的次数 render(){ console.log('render'); //读取状态 const {isHot,wind} = this.state return 今天天气很{isHot ? '炎热' : '凉爽'},{wind} } //changeWeather调用几次? ———— 点几次调几次 changeWeather(){ //changeWeather放在哪里? ———— Weather的原型对象上,供实例使用 //由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用 //类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined//获取原来的isHot值 const isHot = this.state.isHot } } //2.渲染组件到页面 ReactDOM.render(
,document.getElementById('test'))
- 还可以直接在类里面定义的方式来给state赋值,也可以把方法用箭头函数的方式定义在类里,这个时候定义的state和方法都是直接挂载在实例对象上,箭头函数没有自己的this,就会沿用外层实例的this
//1.创建组件 class Weather extends React.Component{ //初始化状态 state = {isHot:false,wind:'微风'} render(){ const {isHot,wind} = this.state return 今天天气很{isHot ? '炎热' : '凉爽'},{wind} } //自定义方法————要用赋值语句的形式+箭头函数 changeWeather = ()=>{ const isHot = this.state.isHot this.setState({isHot:!isHot}) } } //2.渲染组件到页面 ReactDOM.render(
,document.getElementById('test'))
2、三大属性---props 1、基本使用 主要用于给组件传入实参的,传参的时候需要和原型里面的模板内用的变量名称一样。
- 修改state属性不可直接修改,直接修改无法更新在dom中,需要使用setState函数进行更新,且setState只会替换修改的变量和新增变量,这种更新是一种合并,不是替换。
//严重注意:状态必须通过setState进行更新,且更新是一种合并,不是替换。 this.setState({isHot:!isHot}) console.log(this); //严重注意:状态(state)不可直接更改,下面这行就是直接更改!!! //this.state.isHot = !isHot //这是错误的写法
代码如下:
//创建组件
class Person extends React.Component {
render() {
// console.log(this);
const { name, age, sex } = this.props
return (
- 姓名:{name}
- 性别:{sex}
- 年龄:{age + 1}
)
}
}
//渲染组件到页面
ReactDOM.render(, document.getElementById('test1'))
ReactDOM.render(, document.getElementById('test2'))
2、对传入的props参数限制
对props限制一般写在原型对象上3、函数组件使用props
- 第一钟方式是在类外对类对象进行设置,通过.propTypes对标签属性进行类型、必要性的限制;通过.defaultProps指定默认标签属性值
文章图片
- 第二种方式是通过static直接在类的实力上添加静态属性
文章图片
代码如下:
3、三大属性---refs 1、字符串形式的ref(不推荐使用)
文章图片
代码如下:
在组件上设置ref属性值2、回调函数形式的ref
在类中可以通过this.refs通过解构赋值的方式拿到相应组件
showData = https://www.it610.com/article/()=>{ const {input1} = this.refs alert(input1.value) }
如下图:
文章图片
具体代码如下:
使用回调函数形式的时候,回调函数会接收到一个参数,这个参数就是当前的dom元素,然后把这个元素传给this添加的实例对象创建的属性input1上,然后类中的方法通过this可以拿到该dom元素。形式如下:3、createRef的使用(推荐使用)
this.input1 = c } type="text" placeholder="点击按钮提示数据"/>
文章图片
代码如下:
但是这个方式有个问题:
Refs and the DOM – React
文章图片
那就是下次每次更新组件的时候,都会调用两次ref的回调函数,第一次函数传入的是null,第二次是dom元素
文章图片
代码如下:
题外话,再react的jsx怎么注释呢?可以用{}括起来需要注释的语句,{}中是写js的,然后再用js的注释方式:{/* 注释内容*/}
- 首先通过React.createRef()返回一个容器,这个容器可以存储被ref所标识的节点
- 然后再dom元素的ref中用js代码复制这个容器,如:ref={this.myRef}
- 这个容器中有个current对象,就是目前的dom元素,可通过this.myRef.current拿到dom
- 缺点就是有多少个dom需要标记就需要用React.createRef()创造多少个容器,一个容器只能存储一个标识的节点,存储多个会覆盖成最后一个。
文章图片
代码如下:
文章图片
笔记参考于这个视频并添加了自己的总结:尚硅谷2021版React技术全家桶全套完整版(零基础入门到精通/男神天禹老师亲授)_哔哩哔哩_bilibili
推荐阅读
- react技术栈及全家桶|react-router-dom v6 版本使用内容详解
- react.js|react-router-dom V6的配置使用
- react|react 路由(react-router-dom 的使用)
- React报错之Style prop value must be an object
- #|MySQL-高级-7 索引的创建及设计原则
- React|【React-Hooks基础】入门级详解——useState / useEffect /自定义hook
- React|【Redux】如何实现多组件数据共享
- React|<react求和案例>react-redux基本使用与优化——Provider/mapDispatch
- #|vue电商实战(基础理论)day0