react:面向组件编程
面向对象--->面向模块--->面向组件
实现效果:
<MyComponent> <h2>工厂函数组件(简单组件)</h2> </MyComponent> <MyComponent2> <h2>ES6类组件(复杂组件)</h2> </MyComponent2>
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>work3</title> <script src="../js/react.development.js"></script> <script src="../js/react-dom.development.js"></script> <script src="../js/babel.min.js"></script> <script type="text/babel"> //方式一.工厂函数组件(简单组件:没有状态的组件): //1.定义组件 function MyComonent(){ //直接用"渲染"方法 return <h2>工厂函数组件(简单组件)</h2> } //2.渲染组件标签 React.render(<MyComonent />,document.getElementById("example1")) //方式二:ES6类组件(复杂组件) //1.定义组件: class MyComponent2 extends React.Component { //定义了一个组件类的子类;创建实例 render(){ //这个类里有一个render(渲染)方法 return <h2>ES6类组件(复杂组件)</h2> } } //2.渲染组件标签: ReactDOM.render(<MyComonent2 />,document.getElementById("example2")) </script> </head> <body> <div id="example1"></div> <div id="example2"></div> </body> </html>
在组件类里打印this:
class MyComponent2 extends React.Component { render(){ console.log(this) return <h2>ES6类组件(复杂组件)</h2> } }
有三个重要的属性方法:
props:多个属性的集合对象
refs:略过
state:状态
组件的三大属性:
属性一:state
理解:
1.state是组件对象最重要的属性,值是对象(可以包含多个数据)
2.组件被称作“状态机”,通过更新组件的state来更新对应的页面显示(重新渲染组件)
编码操作:
1.初始化状态:
constructor(props){ super(props) this.state={ //this代表组件对象;this.state给状态赋初值 stateProp1:value1, stateProp2:value2 } }
2.读取某个状态值:(读取state内部的某个属性的值)
this.state.statePropertyName
3.更新状态--->组件界面更新(react不会操作DOM只需更新状态)
this.setState({ //更新状态的方法 stateProp1:value1, stateProp2:value2 })
实例代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>work4</title> <script src="../js/react.development.js"></script> <script src="../js/react-dom.development.js"></script> <script src="../js/babel.min.js"></script> <script type="text/babel"> //1.定义组件 class Like extends React.Component{ constructor(props){ //调用父类的构造函数 super(props) //传递props this.state={ //初始化状态 isLikeMe:false //h2里面的内容是变化的,应该有一个布尔类型的标识,两种状态表示两种文本 } //将新增方法的this强制绑定为组件对象,bind方法会产生一个新的函数 this.handleClick=this.handleClick.bind(this) } render(){ //读取状态 //写法一: // const isLikeMe=this.state.isLikeMe; //写法二:解构赋值 const {isLikeMe}=this.state return <h2 onClick={this.handleClick}>{isLikeMe?'都暻秀':'D.O.'}</h2> // 绑定事件 } //注意;以上constructor,render方法为重写组件的方法,但是下面的是新增的方法,新增方法handleClick内部的this默认不是组件对象而是undefined handleClick(){ //更新状态 //得到原先的状态并取反 const isLikeMe=!this.state.isLikeMe // 设置新的状态 this.setState({isLikeMe:isLikeMe}) //ES6新语法,可以简写成:this.setState({isLikeMe}) } } //2.渲染组件标签 ReactDOM.render(<Like />,document.getElementById("example")) </script> </head> <body> <div id="example"></div> </body> </html>
注意:
ReactDOM.render(<Like />,document.getElementById("example")) //如果没有子标签,这里标签写作:<like/>,如果有子标签则写作 ReactDOM.render(<like></like>,document.getElementById("example"))
注意:只要有状态的组件就不能用工厂函数组件
属性二:props
理解:
1.每个组件对象都会有props属性
2.组件标签的所有属性都保存在props
作用:
1.通过标签属性从组件外,向组件内传递变化的数据
2.注意:组件内部不要修改props
编码操作:
1.内部读取某个属性值
this.props.propertyName
2.对props中的属性值进行类型限制和必要限制
//老方法:
Person.propTypes={ name:React.PropTypes.string.isRequired, age:React.PropTypes.number.isRequired }
//新方法:
//prop-types库
Person.propTypes={
name:PropTypes.string.isRequired, //强调了字符串类型和必须项
age:PropTypes.number //只强调数字类型
}
3.扩展属性:将对象的所有属性通过props传递
<Person...{...person}/>
4.默认属性值
Person.defaultProps={ name:"Mary" }
5.组件类的构造函数
constructor(props){ super(props) console.log(props) //查看所有属性值 }
实现效果:一个组件实现多个标签
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>work5</title> <script src="../js/react.development.js"></script> <script src="../js/react-dom.development.js"></script> <script src="../js/babel.min.js"></script> <script src="../js/prop-types.js"></script> <script type="text/babel"> //1.定义组件 //第一种定义方法 /*function Person(props) { return( <ul> <li>姓名:{props.name}</li> <li>性别:{props.age}</li> <li>年龄:{props.sex}</li> </ul> ) }*/ //第二种定义方法: class Person extends React.Component{ render(){ return( <ul> <li>姓名:{this.props.name}</li> <li>性别:{this.props.age}</li> <li>年龄:{this.props.sex}</li> </ul> ) } } //指定属性默认值 Person.defaultProps={ sex:'男', age:18 } //指定属性值的类型和必要性 Person.propTypes={ name:PropTypes.string.isRequired, //强调了字符串类型和必须项 age:PropTypes.number //只强调数字类型 } //2.渲染组件标签 const p1={ name:'Tom', age:100, sex:'女' } //ReactDOM.render(<Person name={p1.name} age={p1.age} sex={p1.sex}/>,document.getElementById("example1")) //简写方法: ReactDOM.render(<Person {...p1}/>,document.getElementById("example1")) const p2={ name:'Jack' } ReactDOM.render(<Person name={p2.name}/>,document.getElementById("example2")) </script> </head> <body> <div id="example1"></div> <div id="example2"></div> </body> </html>
注意 ES6 ... 的作用:
1.打包
//定义方法的时候 function(...as){} //调用的时候 fn(1,2,3,4,5,6)
2.解包
const arr1=[1,2,3];
const arr2=[1,...arr1,4,5,6]
属性三:refs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>work6</title> <script src="../js/react.development.js"></script> <script src="../js/react-dom.development.js"></script> <script src="../js/babel.min.js"></script> <script type="text/babel"> //1.定义组件 class MyComponent extends React.Component{ constructor(props){ super(props) this.showInput=this.showInput.bind(this) this.handleBlur=this.handleBlur.bind(this) } render(){ return( <div> <!-- 第一种方法:不建议用--> <!-- <input type="text" ref="content"/>--> <!--第二种方法:ref成为了一个回调函数,第一次渲染时就会做,此函数是把当前的dom元素保存到组件对象里--> <input type="text" ref={input=>this.input=input}/> <button onClick={this.showInput}>提示输入</button> <input type="text" placeholder="失去焦点提示内容" onBlur={this.handleBlur}/> </div> ) } //自定义的方法 showInput(){ /* 第一种方法: const input=this.refs.content; console.log(input.value) */ //第二种方法: console.log(this.input.value) } handleBlur(event){ console.log(event.target.value) } } //2.渲染组件标签 ReactDOM.render(<MyComponent />,document.getElementById("example")) </script> </head> <body> <div id="example"></div> </body> </html>