React的三大属性
Posted 遥岑.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React的三大属性相关的知识,希望对你有一定的参考价值。
React的三大属性
props属性
组件是封闭的,默认情况下,只能使用组件自己的数据,要接收外部数据应该通过props来实现。
props的作用:接收传递给组件的数据。
传递数据:给组件标签添加属性。
接收数据:函数组件通过参数props接收数据,类组件通过this.props接收数据。
特点:
- 可以给组件传递任意类型的数据
- props是只读对象,只能读取属性的值,无法修改对象
- 使用类组件时,如果写了构造函数,应该将props传递给super(),否则无法再构造函数中获取到props
类组件的构造函数:
constructor(props){
super(props)
console.log(props) //输出组件的所有属性
}
组件通讯
组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。
在组件化过程中,我们将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能。多个组件之间不可避免要共享某些数据,为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通,这个过程就是组件通讯。
父传子
//父组件向子组件传值
class Parent extends React.Component {
constructor(props) {
super(props)
this.state = {
value:'好好生活'
}
}
render() {
return (
<Child say={this.state.value}/>
)
}
}
function Child(props) {
//用props接收父组件传递的数据
return (
<h2>{props.say}</h2>
)
}
子传父
//子组件向父组件传值 通过父组件向子组件传递函数
class Father extends React.Component {
constructor(props) {
super(props)
}
//定义函数 接收值
pull= data => {
console.log(data)
}
render() {
return (
<div>
<Child say={this.pull}/>
</div>
)
}
}
class Child extends React.Component {
constructor(props) {
super(props)
}
state = {
value :'皆如所愿'
}
//调用父组件函数传值
fun=()=> {
this.props.say(this.state.value)
}
render() {
return (
<div>
<button onClick={this.fun}>点击传递数据</button>
</div>
)
}
}
ReactDOM.render(<Father/>,document.querySelector('#col'))
兄弟组件通讯
将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态。
思想:状态提升。
公共父组件的职责:提供共享状态、提供操作共享状态的方法。
要通讯的子组件只需要通过props接收状态或操作状态的方法。
//公共父组件
class Parent extends React.Component {
state = {
count:0
}
fun = () => {
this.setState({
count:this.state.count+1
})
}
render() {
return (
<div>
<Child1 state={this.state.count}/>
<Child2 fun={this.fun}/>
</div>
)
}
}
const Child1 = (props)=> {
return (
<p>计数器:{props.state}</p>
)
}
const Child2 = (props)=> {
return (
<button onClick={props.fun}>+1</button>
)
}
Context
如果两个组件是远房亲戚(比如嵌套多层这样),可以使用Context实现组件通讯。
作用:跨组件传递数据。
使用:
- 调用
React.createContext()
创建Provider(提供数据)
和Consumer(消费数据)
两个组件
const {Provider,Consumer} = React.createContext()
- 使用
Provider
组件作为父节点
<Provider>
<div>
<Child1/>
</div>
</Provider>
- 设置
value
属性,表示要传递的数据
<Provider value='pink'>
- 调用
Consumer
组件接收数据(回调函数)
<Consumer>
{data => <span>data参数表示接收到的数据:{data}</span>}
</Consumer>
例子:
const {Provider,Consumer} = React.createContext()
class Com extends React.Component {
render() {
return (
<Provider value='好好生活'>
<div>
<Com1/>
</div>
</Provider>
)
}
}
function Com1(props) {
return (
<div>
<Com2/>
</div>
)
}
function Com2(props) {
return (
<Consumer>
{data => <span>数据:{data}</span>}
</Consumer>
)
}
ReactDOM.render(<Com/>,document.querySelector('#q'))
children属性
children属性:表示组件标签的子节点,当组件标签有子节点时,props就会有该属性。
children属性与普通的props一样,值可以是任意值。
function Hello(props) {
return (
<div>
组件的子节点: {props.children}
</div>
)
}
ReactDOM.render(<Hello><p>我是子节点</p></Hello>,document.querySelector('#a'))
props校验
props校验:允许在创建组件的时候,就指定props的类型、格式等。
作用:捕获使用组件时因为props导致的错误,给出明确的错误提示,增加组件的健壮性。
属性值的类型和必要性限制:
//在组件外部定义
组件名.propTypes = {
属性名: React.PropTypes.数据类型.必要性(isRequired)
}
//在组件内部定义
static propTypes = {
属性名: PropTypes.数据类型.必要性(isRequired)
}
- 导入prop-types包
约束规则:
- 常见类型:array、bool、func、number、object、string
- React元素类型:element
- 必填项:isRequired
- 特定结构的对象:shape({})
props的默认值
作用:给props设置默认值,在未传入props时生效。
设置Props的默认值:
组件名.defaultProps = {
属性名: 值,
属性名: 值
}
state属性
函数组件叫做无状态组件,类组件又是有状态组件。
是组件的状态机,通过更新组件的state属性来刷新组件(对组件进行重新渲染)。
每个组件都有state,它的值是对象类型。
组件state属性的初始化放在构造方法中。
状态是私有的,只能在组件内部使用。
状态即数据
函数组件没有自己的状态,只负责展示数据
类组件有自己的状态,负责更新UI,让页面动起来
状态值的读取:
this.state.statePropertName
状态值的更新:
setState( )是异步更新数据的。
可以多次调用setState( ),只会触发一次重新渲染。
this.setState({
statePropertName1: 值,
statePropertName2:值
},[callback])
//第二个参数是在状态更新(页面完成重新渲染)后立即执行某个操作
- 不能直接修改state中的值
- setState()作用:修改state,更新UI(父组件重新渲染时,也会重新渲染子组件,但只会渲染当前组件子树)
- 数据驱动视图思想
refs属性
refs是弹性文件系统,在React中可以通过该特性获取Dom或react元素。
使用:
- 通过
createRef()
方法创建
class RefComponent extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef() //创建一个refs 弹性文件系统 获取节点
console.log(this.myRef) //是个对象
}
componentDidMount() { //钩子函数 在组件渲染完成时自动执行
this.myRef.current.innerhtml = '不经一番心彻骨 怎知向何处' //currenrt当前的标签
}
render() {
return (
<div>
<div ref={this.myRef}></div>
</div>
)
}
}
- 可以直接获取html元素:将html元素与ref进行绑定(给标签添加ref属性,ref的属性值就是createRef方法创建的对象)
class Parent extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
//这里的myRef指的是子组件Children
console.log(this.myRef)
}
componentDidMount() {
this.myRef.current.bianshen()
}
render() {
return (
<Children ref={this.myRef}/>
)
}
}
class Children extends React.Component {
bianshen() {
console.log('盼了又盼的归途')
}
render() {
return (
<span>原来是夙慕</span>
)
}
}
- 获取组件类的实例:可以直接和组件类的实例进行绑定
- 回调refs
class Example extends React.Component {
constructor(props){
super(props)
this.targetRef = null
this.myRef = (e)=> this.targetRef = e //参数e默认参数 就是绑定myRef的组件或DOM元素 轻量级
}
componentDidMount() {
if(this.targetRef) {
this.targetRef.innerHTML = '不经一番心彻骨'
}
}
render() {
return (
<div ref={this.myRef}></div>
)
}
}
- 通过绑定字符串(String类型的refs)
class StringRef extends React.Component {
componentDidMount() {
console.log(this.refs.container.innerHTML) //获取绑定的节点
}
render() {
return (
<div ref='container'>怎知向何处</div>
)
}
}
以上是关于React的三大属性的主要内容,如果未能解决你的问题,请参考以下文章
极智开发 | 讲解 React 组件三大属性之二:props