组件化编程是React 和 Vue 框架共同的思想,只是在实现上有些区别,组件化编程的优点不用多说,可以复用,可以简化代码,更能体现封装的思想等。这篇文章主要是定义结合代码分享React组件的基本使用和组件三大属性。
组件基本定义和使用
组件定义
React 组件的定义有两种方式,分别是 工厂函数组件(简单组件);ES6 类组件(复杂组件==》可以操作state)
使用
使用分主要两步,定义组件 ====》 渲染组件标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件的基本定义和使用</title>
</head>
<body>
<div id="example1"></div>
<div id="example2"></div>
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script type="text/babel">
// 组件化编程 基本组件定义和使用 组件三大属性 组件组合使用 组件生命周期
//1、定义组件
/* 方式1 工厂函数组件 简单组件 组件有状态就不能用工厂模式*/
function MyComponent(){
return <h2>工厂函数组件(简单组件)</h2>
}
/* 方式2 ES6 类组件(复杂组件)*/
class MyCompinent2 extends React.Component{
render(){
console.log(this)
return <h2>ES6 类组件(复杂组件)</h2>
}
}
// 2、 渲染组件标签
ReactDOM.render(<MyComponent/>,document.getElementById('example1'))
ReactDOM.render(<MyCompinent2/>,document.getElementById('example2'))
</script>
</body>
</html>
定义组件注意:
- 组件名必须首字母大写
- 虚拟DOM元素只能有一个根元素
- 虚拟DOM元素必须有结束标签
render()渲染组件标签的基本流程
- React 会创建组件实例对象
- 得到包含的虚拟DOM 并解析为真实DOM
- 插入到指定的页面元素内部
最后看一下组件对象长什么样,每个组件都包含了 state props refs 属性 ,如下展示的就是默认值
三大属性之 state
基本理解:
state 是React 组件对象最重要的属性,state本身是对象,可以包含很多数据,是统一数据管理的对象,React中改变DOM 渲染内容是通过改变数据来的,而数据时通过state 管理的 ,因此要操作state,数据处理比vue 对 state 的依赖大。
一般步骤:
- 初始化状态 ===》一般在constructor 中 初始化
- 读取状态===》在render() 函数中读取
- 更新状态===》一般在事件处理函数中
codding
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>组件三大属性之 state</title>
</head>
<body>
<div id='example'></div>
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script type="text/babel">
/*
需求:自定义组件 功能说明如下
1、显示h2 标题 初始文本为 你喜欢我
2、点击标题更新为:我喜欢你
*/
// 1、 定义组件
class Like extends React.Component{
constructor(props){
super(props)
// 初始化状态
this.state = {
isLikeMe : false
}
// 将新增方法中的this 强制绑定为组件对象
this.handleClick = this.handleClick.bind(this)
}
// 新增加的方法:内部的this 默认不是组件对象 而是undefined
handleClick(){
// console.log(this)
// 更新状态
const isLikeMe = !this.state.isLikeMe
this.setState({isLikeMe})
}
// 重写组件类的方法
render(){
// 读取状态
const {isLikeMe} = this.state
return <h2 onClick={this.handleClick}>{isLikeMe ? '你喜欢我':'我喜欢你'}</h2>
}
}
// 2、渲染组件
ReactDOM.render(<Like/>,document.getElementById('example'))
</script>
</body>
</html>
注意
自定义组件新增的函数如 handleClick( 非重写的函数) 默认 this 是 undefined ,如果想在此函数中使用组件对象this ,则需要借助bind。
三大属性之 props
基本理解
props 是组件对象包含的自定义属性的集合对象,每个组件都会有,自定义属性都含在其中,可以通过标签属性从组件外向组件内传值,因此组件内不要修改props 数据,要在组件外修改后传入,也可以更好的复用。
codding
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>组件三大属性之 props </title>
</head>
<body>
<div id='example1'></div>
<div id='example2'></div>
<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js"></script>
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
// 需求: 自定义用来显示一个人员信息的组件
// 1). 姓名必须指定
// 2). 如果性别没有指定, 默认为男
// 3). 如果年龄没有指定, 默认为18
// 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:16,
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} age={20}/>,document.getElementById('example2'))
</script>
</body>
</html>
补充:React props 属性传值,和 vue 类似,都是可以设置默认值 以及 规定数据类型 可以通过扩展属性传值 api 可参考如上代码。
三大属性之 refs
基本理解
React refs 属性和 vue 中的是一样的,是用来标识组件用的,向自定义属性的id 一样, 虽然vue 在后 但是没办法 转行之后先学的 vue ,React 学起来有点繁琐,但是应该有其致胜之处,听说很多大项目都是用React 框架。
demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>组件三大属性之 refs</title>
</head>
<body>
<div id='example'></div>
<div id='example2'></div>
<script type="text/javascript" src="./js/react.development.js"></script>
<script type="text/javascript" src="./js/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js"></script>
<script type="text/javascript" src="./js/babel.min.js"></script>
<script type="text/babel">
// 需求: 自定义组件, 功能说明如下:
// 2. 点击按钮, 提示第一个输入框中的值
// 3. 当第2个输入框失去焦点时, 提示这个输入框中的值
// 理解
// 1) 组件内的标签都可以定义ref属性来标识自己
// a. <input type="text" ref={input => this.msgInput = input}/>
// b. 回调函数在组件初始化渲染完或卸载时自动调用
// 2) 在组件中可以通过this.msgInput来得到对应的真实DOM元素
// 3) 作用: 通过ref获取组件内容特定标签对象, 进行读取其相关数据
// 定义组件
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'/>
<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
// alert(input.value)
alert(this.input.value)
}
handleBlur(e){
alert(e.target.value)
}
}
// 渲染组件标签
ReactDOM.render(<MyComponent/> ,document.getElementById('example'))
</script>
</body>
</html>
看代码中,ref 的定义有两种 :
- <input type="text" ref='content'/>
- <input type="text" ref={input=>this.input=input}/>
到此了解了React 组件的基本使用,和 组件的三大属性 state props refs ,基本使用每个属性的使用都有一个小的demo 需求,此篇博客用于自己的学习记录,如果有初学者向了解一下也可以参考希望自己的记录梳理有帮助。