前言
开发一个React应用,更多的是在编写组件,而React组件最小的单位就是React元素,编写组件的最大的好处,就是实现代码的复用
将一个大的应用按照功能结构等划分成若干个部分(组件),对每个部分(组件)进行分开管理,与组件相关的东西放在一起,达到高内聚的目的,而不同组件又各自独立管理达到低耦合的效果。
构建组件,本质上就是在编写javascript函数,而组件中最重要的是数据,在React中数据分两种:props和state,当定义一个组件时,它接收任意的形参(即props),并用于返回描述页面展示内容的React元素
无论props还是state,当他们任一一个发生改变时,都会引发render函数的重新渲染
一个UI组件所渲染的结果,就是通过props和state这两个属性在render方法里面映射生成对应的HTML结构
那么在写一个React组件的时候,究竟什么时候使用state,什么时候使用props呢?如何的划分组件的状态数据?
那么本节就是你想要知道的
React中的props
当通过函数声明或者class自定义一个组件时,它会将JSX所接受的属性(attributes)转换为一对象传递给该定义时的组件
这个接收的对象就是props(property的简写),props就是组件定义属性的集合,它是组件对外的接口,由外部通过JSX属性传入设置(也就是从外部传递给内部组件的数据)
一个React组件通过定义自己能够接收的prop,就定义了自己对外提供的公共接口
每个定义的React组件应该都是独立存在的模块,组件之外的一切都是外部世界(组件),外部世界(组件)就是通过prop来和组件进行对话数据传递的
在React中,你可以将prop类似于HTML标签元素的属性,不过原生HTML标签的属性值都是字符串,即使是内嵌js表达式,也依然是字符串,而在React中,prop的属性值类型可以任何数据类型(基本数据类型(number,String,null等函数)或者对象)
当然如果是非字符串数据类型,在JSX中,必须要用花括号{}把prop值给包裹起来
这也是为什么style有两层花括号的原因:最外层代表的是JSX语法,意味着它是一个变量对象,而内层的花括号{}代表的是一个对象
在函数声明自定义的组件中,可以通过props获取组件的属性
如下所示:自定义一个Button组件,给组件添加各个属性值,渲染的结果如下所示
函数式组件:通过function关键字声明,组件首字母大写
import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
// 函数式组件,定义一个Button组件,首字母大写
function Button(props) {
console.log(props); // 将会把调用处组件的style属性给打印出来
const btnStyles = {
width: props.style.width,
height: props.style.height,
background: props.style.background,
color: props.style.color,
border: props.style.border,
outline: props.style.outline,
cursor: props.style.cursor
};
return (
<div>
<button style = { btnStyles }>按钮</button>
</div>
);
}
const btnStyle = {
width: "100px",
height: "40px",
background: "orange",
color: "#fff",
border: "none",
outline: "none",
cursor: "pointer"
}
const container = document.getElementById('root');
ReactDOM.render(<Button style = { btnStyle } />, container);
类class声明的组件: 通过Es6中的class声明,继承React.Component进行实现
import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
// 类组件,通过class关键字声明使用
class Button extends Component {
constructor(props){
super(props);
}
render() {
console.log(this.props);
// 这里利用Es6中的解构赋值
const { width, height, background, color, border, outline,cursor} = this.props.style;
const btnStyles = {
width, // 等于width:width
height,
background,
color,
border,
outline,
cursor
}
return (
<div>
<button style = { btnStyles }>按钮</button>
</div>
);
}
}
// 该Button组件按钮自身拥有的属性
const btnStyle = {
width: "100px",
height: "40px",
background: "orange",
color: "#fff",
border: "none",
outline: "none",
cursor: "pointer"
}
const container = document.getElementById('root');
ReactDOM.render(<Button style = { btnStyle } />, container);
上述代码中分别使用了函数式组件与类声明的组件,在调用组件时,对组件设置了props值,而在组件内部通过this.props获取属性值
从而得出,父组件(外部组件)向子(内)组件传值是通过设置JSX属性的方式实现的,而在子组件内部获取父(外部)组件数据是通过this.props来获取的,也可以这么认为,props就是对外提供的数据接口
对于用类class声明的组件,读取prop的值,是通过this.props来获取的
首先用construcor定义了一个构造函数,并且给它接收了一个props形参,然后在constructor构造器函数内调用super(props)