目录
- 1、介绍
- 2、state
- 概念
- 演示
- 3、props
- 概念
- props与state区别
- 4、refs
- 概念
- refs种类
- 5、父子组件
- 什么是父子组件
- 父子组件之间传值
1、介绍
React组件中默认封装了很多属性,有的是提供给开发者操作的,其中有三个属性非常重要:state、props、refs。
2、state
概念
state是类组件的一个默认属性,用于标识类组件的状态,负责更新UI,让页面动态变化,当state变化时,组件将被重新渲染。
函数组件没有对象属性(babel默认开启了局部严格模式,函数内部this指向undefined),所以函数组件没有state属性,因此函数组件只负责展示静态页面。
state的值是json对象类型,可以维护多个key-value的组合。
演示
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>state属性</title> | |
</head> | |
<body> | |
<div id="container"></div> | |
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> | |
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> | |
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script> | |
<script type="text/babel" > | |
class ClassComponet extends React.Component{ | |
count = 0; | |
//初始化state状态属性,值必须为对象 | |
state = {now: new Date()}; | |
//state对象里面的任何值变化,render都会被重新调用 | |
render(){ | |
console.log(this.count++); | |
return ( | |
<div> | |
<h1>当前时间:{this.state.now.toString()}</h1> | |
<button onClick={this.changeTime}>时间开始动起来</button> | |
</div> | |
); | |
} | |
changeTime = ()=>{ | |
clearInterval(this.timer); | |
this.timer = setInterval(()=>{ | |
//注意:状态必须通过setState进行更新,否则无效 | |
this.setState({now: new Date()}); | |
},1000); | |
} | |
} | |
ReactDOM.render(<ClassComponet/>,document.getElementById('container')) | |
</script> | |
</body> | |
</html> |
3、props
概念
props是组件的一个默认属性,用于组件外部向组件内部传值,或者组件之间相互进行传值。
每个组件都有props属性(原理:函数组件通过参数往内部传值,类组件通过构造器往内部传值)。
props属性值是只读的,组件自身不能修改props属性值。
组件的props属性值可以进行类型、必要性限制,也可以设置属性默认值。
props与state区别
- props是组件对外的,state是组件对内的。
- state属性值是可变的,props属性值是只读的。
演示
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>props属性</title> | |
</head> | |
<body> | |
<div id="container"></div> | |
<div id="container2"></div> | |
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> | |
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> | |
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script> | |
<!-- 使用PropTypes需要引入prop-types --> | |
<script src="https://unpkg.com/prop-types@15.6/prop-types.js"></script> | |
<script type="text/babel" > | |
class Person extends React.Component{ | |
render(){ | |
//解构赋值取出props内部属性 | |
const {name,age,gender} = this.props; | |
return ( | |
<div> | |
<ul> | |
<li>姓名:{name}</li> | |
<li>性别:{age}</li> | |
<li>年龄:{gender}</li> | |
</ul> | |
</div> | |
); | |
} | |
//对props属性值进行类型、必要性的限制(此属性针对类层面,所以定义为static) | |
//使用PropTypes需要引入prop-types | |
static propTypes = { | |
name:PropTypes.string.isRequired, //限制name必传,且为字符串 | |
sex:PropTypes.string,//限制sex为字符串 | |
age:PropTypes.number,//限制age为数值 | |
speak:PropTypes.func,//限制speak为函数 | |
} | |
//对props属性值设置默认值,当外部未传递时就会采用默认值 | |
static defaultProps = { | |
sex:'男',//sex默认值为男 | |
age:100 //age默认值为18 | |
} | |
} | |
//通过组件标签属性向组件对象内部传递props属性值 | |
ReactDOM.render(<Person name="张三" age={18} gender="男"/>,document.getElementById('container')) | |
//通过展开运算向组件对象内部传递props属性值 | |
const person = {'name':'李四','age':20,'gender':'女'}; | |
ReactDOM.render(<Person {...person}/>,document.getElementById('container2')) | |
</script> | |
</body> | |
</html> |
4、refs
概念
组件内的标签,可以在标签上定义ref属性,用于标识标签自身,组件内便可以通过ref属性值获取到操作页面的真实DOM。
refs种类
- 字符串形式的ref
- 回调函数形式的ref
- React.createRef形式的ref
演示
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>refs属性</title> | |
</head> | |
<body> | |
<div id="container"></div> | |
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> | |
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> | |
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script> | |
<script type="text/babel" > | |
class ClassComponet extends React.Component{ | |
//React.createRef调用后可以返回一个容器,该容器仅能存储一个被ref所标识的节点 | |
msg3 = React.createRef() | |
render(){ | |
return ( | |
<div> | |
输入框1:<input ref="msg1" type="text"/> <br/> {/*字符串形式的ref*/} | |
输入框2:<input ref={this.setInput2Ref} type="text"/> <br/> {/*回调函数形式的ref*/} | |
输入框3:<input ref={this.msg3} type="text"/> <br/> {/*React.createRef形式的ref*/} | |
<button onClick={this.showData1}>点击弹出输入框1内容</button> <br/> | |
<button onClick={this.showData2}>点击弹出输入框2内容</button> <br/> | |
<button onClick={this.showData3}>点击弹出输入框3内容</button> <br/> | |
</div> | |
); | |
} | |
showData1 = ()=>{ | |
alert(this.refs.msg1.value); | |
} | |
//传递的参数就是标签位于页面的真实DOM,保存到组件中后续使用 | |
setInput2Ref = (realDOM)=>{ | |
this.msg2 = realDOM; | |
} | |
showData2 = ()=>{ | |
alert(this.msg2.value); | |
} | |
showData3 = ()=>{ | |
//React.createRef创建的容器存储被ref所标识的节点,需要通过current属性获取 | |
alert(this.msg3.current.value); | |
} | |
} | |
ReactDOM.render(<ClassComponet/>,document.getElementById('container')) | |
</script> | |
</body> | |
</html> |
5、父子组件
什么是父子组件
当组件之间嵌套使用时,外层组件就被称为父组件,内层组件就被称为子组件。
父子组件之间传值
这里借助state、props两大组件属性进行父子组件之间传值。
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>父子组件间传值</title> | |
</head> | |
<body> | |
<div id="container"></div> | |
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> | |
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> | |
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script> | |
<script type="text/babel" > | |
//父组件 | |
class FatherComponet extends React.Component{ | |
name = "小头爸爸"; | |
state = {sonName:""} | |
getSonName = (sonName)=>{ | |
this.setState({sonName}) | |
return sonName; | |
} | |
render(){ | |
return ( | |
<div> | |
<h2>我是父组件:{this.name},我的儿子是:{this.state.sonName}</h2> | |
<SonComponet name={this.name} getSonName={this.getSonName}/> {/*引入子组件,且通过props属性给子组件传值*/} | |
</div> | |
); | |
} | |
} | |
//子组件 | |
class SonComponet extends React.Component{ | |
name = "大头儿子"; | |
render(){ | |
const {name:fatherName} = this.props; | |
return ( | |
<div> | |
<h3>我是子组件:{this.name},我爸爸是:{fatherName}</h3> | |
<button onClick={this.myNameSendFather}>子组件传值给父组件</button> | |
</div> | |
); | |
} | |
myNameSendFather = ()=>{ | |
const {getSonName} = this.props; | |
//子组件调用父组件的函数,通过参数将值传递给父组件 | |
getSonName(this.name); | |
} | |
} | |
ReactDOM.render(<FatherComponet/>,document.getElementById('container')) | |
</script> | |
</body> | |
</html> |