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

React 全栈体系(二)

第二章 React面向组件编程

一、基本理解和使用

1. 使用React开发者工具调试

请添加图片描述

2. 效果

2.1 函数式组件

请添加图片描述

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>1_函数式组件</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel">//1.创建函数式组件function MyComponent(){console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>}//2.渲染组件到页面ReactDOM.render(<MyComponent/>,document.getElementById('test'))/* 执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?1.React解析组件标签,找到了MyComponent组件。2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面中。*/</script>
</body>
</html>

2.2 复习

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>类的基本知识</title>
</head>
<body><script type="text/javascript" >/* 总结:1.类中的构造器不是必须要写的,要对实例进行一些初始化的操作,如添加指定属性时才写。2.如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须要调用的。3.类中所定义的方法,都放在了类的原型对象上,供实例去使用。*///创建一个Person类class Person {//构造器方法constructor(name,age){//构造器中的this是谁?—— 类的实例对象this.name = namethis.age = age}//一般方法speak(){//speak方法放在了哪里?——类的原型对象上,供实例使用//通过Person实例调用speak时,speak中的this就是Person实例console.log(`我叫${this.name},我年龄是${this.age}`);}}//创建一个Student类,继承于Person类class Student extends Person {constructor(name,age,grade){super(name,age)this.grade = gradethis.school = '小帽学堂'}//重写从父类继承过来的方法speak(){console.log(`我叫${this.name},我年龄是${this.age},我读的是${this.grade}年级`);this.study()}study(){//study方法放在了哪里?——类的原型对象上,供实例使用//通过Student实例调用study时,study中的this就是Student实例console.log('我很努力的学习');}}class Car {constructor(name,price){this.name = namethis.price = price// this.wheel = 4}//类中可以直接写赋值语句,如下代码的含义是:给Car的实例对象添加一个属性,名为a,值为1a = 1wheel = 4static demo = 100}const c1 = new Car('奔驰c63',199)console.log(c1);console.log(Car.demo);</script>
</body>
</html>

2.3 类式组件

请添加图片描述

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>2_类式组件</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel">//1.创建类式组件class MyComponent extends React.Component {render(){//render是放在哪里的?—— MyComponent的原型对象上,供实例使用。//render中的this是谁?—— MyComponent的实例对象 <=> MyComponent组件实例对象。console.log('render中的this:',this);return <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>}}//2.渲染组件到页面ReactDOM.render(<MyComponent/>,document.getElementById('test'))/* 执行了ReactDOM.render(<MyComponent/>.......之后,发生了什么?1.React解析组件标签,找到了MyComponent组件。2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。*/</script>
</body>
</html>

3. 注意

  • 组件名必须首字母大写
  • 虚拟DOM元素只能有一个根元素
  • 虚拟DOM元素必须有结束标签

4. 渲染类组件标签的基本流程

  • React内部会创建组件实例对象
  • 调用render()得到虚拟DOM, 并解析为真实DOM
  • 插入到指定的页面元素内部

二、组件三大核心属性1: state

1. 效果

  • 需求: 定义一个展示天气信息的组件
    • 默认展示天气炎热 或 凉爽
    • 点击文字切换天气

2. 复习

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>原生事件绑定</title></head><body><button id="btn1">按钮1</button><button id="btn2">按钮2</button><button onclick="demo()">按钮3</button><script type="text/javascript" >const btn1 = document.getElementById('btn1')btn1.addEventListener('click',()=>{alert('按钮1被点击了')})const btn2 = document.getElementById('btn2')btn2.onclick = ()=>{alert('按钮2被点击了')}function demo(){alert('按钮3被点击了')}</script></body>
</html>
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>类方法中的this指向</title></head><body><script type="text/javascript" >class Person {constructor(name,age){this.name = namethis.age = age}study(){//study方法放在了哪里?——类的原型对象上,供实例使用//通过Person实例调用study时,study中的this就是Person实例console.log(this);}}const p1 = new Person('tom',18)p1.study() //通过实例调用study方法const x = p1.studyx()</script></body>
</html>

3. 理解

  • state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
  • 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

4. 强烈注意

  • 组件中render方法中的this为组件实例对象
  • 组件自定义的方法中this为undefined,如何解决?
    • 强制绑定this: 通过函数对象的bind()
    • 箭头函数
  • 状态数据,不能直接修改或更新
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>state</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel">//1.创建组件class Weather extends React.Component{//构造器调用几次? ———— 1次constructor(props){console.log('constructor');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.statereturn <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'}{wind}</h1>}//changeWeather调用几次? ———— 点几次调几次changeWeather(){//changeWeather放在哪里? ———— Weather的原型对象上,供实例使用//由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用//类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefinedconsole.log('changeWeather');//获取原来的isHot值const isHot = this.state.isHot//严重注意:状态必须通过setState进行更新,且更新是一种合并,不是替换。this.setState({isHot:!isHot})console.log(this);//严重注意:状态(state)不可直接更改,下面这行就是直接更改!!!//this.state.isHot = !isHot //这是错误的写法}}//2.渲染组件到页面ReactDOM.render(<Weather/>,document.getElementById('test'))</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>state简写方式</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel">//1.创建组件class Weather extends React.Component{//初始化状态state = {isHot:false,wind:'微风'}render(){const {isHot,wind} = this.statereturn <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'}{wind}</h1>}//自定义方法————要用赋值语句的形式+箭头函数changeWeather = ()=>{const isHot = this.state.isHotthis.setState({isHot:!isHot})}}//2.渲染组件到页面ReactDOM.render(<Weather/>,document.getElementById('test'))</script>
</body>
</html>

三、组件三大核心属性2: props

1. 效果

  • 需求: 自定义用来显示一个人员信息的组件
    • 姓名必须指定,且为字符串类型;
    • 性别为字符串类型,如果性别没有指定,默认为男
    • 年龄为字符串类型,且为数字类型,默认值为18
      请添加图片描述

2. 理解

  • 每个组件对象都会有props(properties的简写)属性
  • 组件标签的所有属性都保存在props中

3. 作用

  • 通过标签属性从组件外向组件内传递变化的数据
  • 注意: 组件内部不要修改props数据

4. 编码操作

4.1 内部读取某个属性值

this.props.name

4.2 对props中的属性值进行类型限制和必要性限制

  • 第一种方式(React v15.5 开始已弃用):
Person.propTypes = {name: React.PropTypes.string.isRequired,age: React.PropTypes.number
}
  • 第二种方式(新):使用prop-types库进限制(需要引入prop-types库)
Person.propTypes = {name: PropTypes.string.isRequired,age: PropTypes.number
}

4.3 扩展属性: 将对象的所有属性通过props传递

<Person {...person}/>

4.4 默认属性值

Person.defaultProps = {age: 18,sex:'男'
}

4.5 组件类的构造函数

constructor(props){super(props)console.log(props)//打印所有属性
}

5. 代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>props基本使用</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test1"></div><div id="test2"></div><div id="test3"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><script type="text/babel">//创建组件class Person extends React.Component{render(){// console.log(this);const {name,age,sex} = this.propsreturn (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age+1}</li></ul>)}}//渲染组件到页面ReactDOM.render(<Person name="jerry" age={19}  sex="男"/>,document.getElementById('test1'))ReactDOM.render(<Person name="tom" age={18} sex="女"/>,document.getElementById('test2'))const p = {name:'老刘',age:18,sex:'女'}// console.log('@',...p);// ReactDOM.render(<Person name={p.name} age={p.age} sex={p.sex}/>,document.getElementById('test3'))ReactDOM.render(<Person {...p}/>,document.getElementById('test3'))</script>
</body>
</html>
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>展开运算符</title></head><body><script type="text/javascript" >let arr1 = [1,3,5,7,9]let arr2 = [2,4,6,8,10]console.log(...arr1); //展开一个数组let arr3 = [...arr1,...arr2]//连接数组//在函数中使用function sum(...numbers){return numbers.reduce((preValue,currentValue)=>{return preValue + currentValue})}console.log(sum(1,2,3,4));//构造字面量对象时使用展开语法let person = {name:'tom',age:18}let person2 = {...person}//console.log(...person); //报错,展开运算符不能展开对象person.name = 'jerry'console.log(person2);console.log(person);//合并let person3 = {...person,name:'jack',address:"地球"}console.log(person3);</script></body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>对props进行限制</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test1"></div><div id="test2"></div><div id="test3"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入prop-types,用于对组件标签属性进行限制 --><script type="text/javascript" src="../js/prop-types.js"></script><script type="text/babel">//创建组件class Person extends React.Component{render(){// console.log(this);const {name,age,sex} = this.props//props是只读的//this.props.name = 'jack' //此行代码会报错,因为props是只读的return (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age+1}</li></ul>)}}//对标签属性进行类型、必要性的限制Person.propTypes = {name:PropTypes.string.isRequired, //限制name必传,且为字符串sex:PropTypes.string,//限制sex为字符串age:PropTypes.number,//限制age为数值speak:PropTypes.func,//限制speak为函数}//指定默认标签属性值Person.defaultProps = {sex:'男',//sex默认值为男age:18 //age默认值为18}//渲染组件到页面ReactDOM.render(<Person name={100} speak={speak}/>,document.getElementById('test1'))ReactDOM.render(<Person name="tom" age={18} sex="女"/>,document.getElementById('test2'))const p = {name:'老刘',age:18,sex:'女'}// console.log('@',...p);// ReactDOM.render(<Person name={p.name} age={p.age} sex={p.sex}/>,document.getElementById('test3'))ReactDOM.render(<Person {...p}/>,document.getElementById('test3'))function speak(){console.log('我说话了');}</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>props的简写形式</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test1"></div><div id="test2"></div><div id="test3"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入prop-types,用于对组件标签属性进行限制 --><script type="text/javascript" src="../js/prop-types.js"></script><script type="text/babel">//创建组件class Person extends React.Component{constructor(props){//构造器是否接收props,是否传递给super,取决于:是否希望在构造器中通过this访问props// console.log(props);super(props)console.log('constructor',this.props);}//对标签属性进行类型、必要性的限制static propTypes = {name:PropTypes.string.isRequired, //限制name必传,且为字符串sex:PropTypes.string,//限制sex为字符串age:PropTypes.number,//限制age为数值}//指定默认标签属性值static defaultProps = {sex:'男',//sex默认值为男age:18 //age默认值为18}render(){// console.log(this);const {name,age,sex} = this.props//props是只读的//this.props.name = 'jack' //此行代码会报错,因为props是只读的return (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age+1}</li></ul>)}}//渲染组件到页面ReactDOM.render(<Person name="jerry"/>,document.getElementById('test1'))</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>函数组件使用props</title>
</head>
<body><!-- 准备好一个“容器” --><div id="test1"></div><div id="test2"></div><div id="test3"></div><!-- 引入react核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入react-dom,用于支持react操作DOM --><script type="text/javascript" src="../js/react-dom.development.js"></script><!-- 引入babel,用于将jsx转为js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入prop-types,用于对组件标签属性进行限制 --><script type="text/javascript" src="../js/prop-types.js"></script><script type="text/babel">//创建组件function Person (props){const {name,age,sex} = propsreturn (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age}</li></ul>)}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(<Person name="jerry"/>,document.getElementById('test1'))</script>
</body>
</html>
http://www.lryc.cn/news/138029.html

相关文章:

  • 【Linux】socket编程(二)
  • 七大出海赛道解读,亚马逊云科技为行业客户量身打造解决方案
  • 【Maven教程】(三)基础使用篇:入门使用指南——POM编写、业务代码、测试代码、打包与运行、使用Archetype生成项目骨架~
  • Spring Boot + Spring Data JPA 实现数据库操作的标准示例
  • JVM——类加载器
  • async/await 编程理解
  • 1. Java基础知识介绍
  • 基础shell小技巧01
  • 微信小程序--data的赋值与取值的几种方式
  • 条码通讯配置
  • 知网G4期刊《高考》简介及投稿要求
  • 第7章 CPU前端优化
  • idea新建Java-maven项目时,出现Dependency‘xxx(jar包名)‘ not found的解决方案
  • STM32--USART串口
  • 2023年Java毕业设计题目推荐,怎样选题?500道毕业设计题目推荐
  • 基于数据湖的多流拼接方案-HUDI概念篇
  • OpenCV基础知识(5)— 几何变换
  • Linux下源码安装MySQL 8.0
  • 大聪明教你学Java | 深入浅出聊 Java 内存模型
  • SAP ABAPG开发屏幕自动生成日期的搜索帮助
  • leetcode 674. 最长连续递增序列
  • Mysql简短又易懂
  • vue 简单实验 v-model 变量和htm值双向绑定
  • 测试框架pytest教程(8)失败重试-pytest-rerunfailures
  • 6个主流的工业3D管道设计软件
  • 基于微信小程序的垃圾分类系统设计与实现(2.0 版本,附前后端代码)
  • 基础论文学习(4)——CLIP
  • SpringBoot利用ConstraintValidator实现自定义注解校验
  • 十、pikachu之php反序列化
  • PHP“牵手”拼多多商品详情数据获取方法,拼多多API接口批量获取拼多多商品详情数据说明