第二章 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 = namethis . age = age} speak ( ) { console. log ( ` 我叫 ${ this . name} ,我年龄是 ${ this . age} ` ) ; } } 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 ( ) { console. log ( '我很努力的学习' ) ; } } class Car { constructor ( name, price ) { this . name = namethis . 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 = namethis . age = age} study ( ) { console. log ( this ) ; } } const p1 = new Person ( 'tom' , 18 ) p1. 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> < 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 . statereturn < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '凉爽' } ,{ wind} < / h1> } changeWeather ( ) { console. log ( 'changeWeather' ) ; const isHot = this . state. isHotthis . 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 . statereturn < h1 onClick= { this . changeWeather} > 今天天气很{ isHot ? '炎热' : '凉爽' } ,{ wind} < / h1> } changeWeather = ( ) => { const isHot = this . state. isHotthis . 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 . 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 : '女' } 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 . propsreturn ( < 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 . propsreturn ( < 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} = propsreturn ( < 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>