第二章 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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/babel" >
function MyComponent ( ) {
console. log ( this ) ;
return < h2> 我是用函数定义的组件 ( 适用于【简单组件】的定义) < / h2>
}
ReactDOM. render ( < MyComponent/ > , document. getElementById ( 'test' ) )
</ script>
</ body>
</ html>
2.2 复习
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 类的基本知识</ title>
</ head>
< body>
< script type = " text/javascript" >
class Person {
constructor ( name, age ) {
this . name = name
this . age = age
}
speak ( ) {
console. log ( ` 我叫 ${ this . name} ,我年龄是 ${ this . age} ` ) ;
}
}
class Student extends Person {
constructor ( name, age, grade ) {
super ( name, age)
this . grade = grade
this . school = '小帽学堂'
}
speak ( ) {
console. log ( ` 我叫 ${ this . name} ,我年龄是 ${ this . age} ,我读的是 ${ this . grade} 年级 ` ) ;
this . study ( )
}
study ( ) {
console. log ( '我很努力的学习' ) ;
}
}
class Car {
constructor ( name, price ) {
this . name = name
this . price = price
}
a = 1
wheel = 4
static 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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/babel" >
class MyComponent extends React. Component {
render ( ) {
console. log ( 'render中的this:' , this ) ;
return < h2> 我是用类定义的组件 ( 适用于【复杂组件】的定义) < / h2>
}
}
ReactDOM. render ( < MyComponent/ > , document. getElementById ( 'test' ) )
</ 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 = name
this . age = age
}
study ( ) {
console. log ( this ) ;
}
}
const p1 = new Person ( 'tom' , 18 )
p1. study ( )
const x = p1. study
x ( )
</ 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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/babel" >
class Weather extends React. Component {
constructor ( props ) {
console. log ( 'constructor' ) ;
super ( props)
this . state = { isHot : false , wind : '微风' }
this . changeWeather = this . changeWeather . bind ( this )
}
render ( ) {
console. log ( 'render' ) ;
const { isHot, wind} = this . state
return < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '凉爽' } ,{ wind} < / h1>
}
changeWeather ( ) {
console. log ( 'changeWeather' ) ;
const isHot = this . state. isHot
this . setState ( { isHot : ! isHot} )
console. log ( this ) ;
}
}
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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/babel" >
class Weather extends React. Component {
state = { isHot : false , wind : '微风' }
render ( ) {
const { isHot, wind} = this . state
return < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '凉爽' } ,{ wind} < / h1>
}
changeWeather = ( ) => {
const isHot = this . state. isHot
this . setState ( { isHot : ! isHot} )
}
}
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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/babel" >
class Person extends React. Component {
render ( ) {
const { name, age, sex} = this . props
return (
< 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 : '女' }
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}
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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/javascript" src = " ../js/prop-types.js" > </ script>
< script type = " text/babel" >
class Person extends React. Component {
render ( ) {
const { name, age, sex} = this . props
return (
< ul>
< li> 姓名:{ name} < / li>
< li> 性别:{ sex} < / li>
< li> 年龄:{ age+ 1 } < / li>
< / ul>
)
}
}
Person. propTypes = {
name : PropTypes. string. isRequired,
sex : PropTypes. string,
age : PropTypes. number,
speak : PropTypes. func,
}
Person. defaultProps = {
sex : '男' ,
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 : '女' }
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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/javascript" src = " ../js/prop-types.js" > </ script>
< script type = " text/babel" >
class Person extends React. Component {
constructor ( props ) {
super ( props)
console. log ( 'constructor' , this . props) ;
}
static propTypes = {
name : PropTypes. string. isRequired,
sex : PropTypes. string,
age : PropTypes. number,
}
static defaultProps = {
sex : '男' ,
age : 18
}
render ( ) {
const { name, age, sex} = this . 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>
< script type = " text/javascript" src = " ../js/react.development.js" > </ script>
< script type = " text/javascript" src = " ../js/react-dom.development.js" > </ script>
< script type = " text/javascript" src = " ../js/babel.min.js" > </ script>
< script type = " text/javascript" src = " ../js/prop-types.js" > </ script>
< script type = " text/babel" >
function Person ( props ) {
const { name, age, sex} = props
return (
< ul>
< li> 姓名:{ name} < / li>
< li> 性别:{ sex} < / li>
< li> 年龄:{ age} < / li>
< / ul>
)
}
Person. propTypes = {
name : PropTypes. string. isRequired,
sex : PropTypes. string,
age : PropTypes. number,
}
Person. defaultProps = {
sex : '男' ,
age : 18
}
ReactDOM. render ( < Person name= "jerry" / > , document. getElementById ( 'test1' ) )
</ script>
</ body>
</ html>