1、什么是组件
一个应用/版块/页面中用于实现某个局部的功能(包括html, js, css等)把这些局部功能组装到一起,就形成了组件
2、如何创建组件
组件分为两种,一种是函数组件,另外一种是class类组件
我们首先来看一下函数组件的创建,代码如下:
import React from 'react'; //引入React模块
function A() { //创建函数组件
return (
<div>
我是一个函数组件
</div>
);
}
export default A;
然后是class组件的创建,代码如下:
import React from 'react';
class B extends React.Component{ //创建class组件
render(){
return (
<div>
我是一个class组件
</div>
);
}
}
export default B;
在其他文件中引用组件,代码如下:
import React from 'react';
import ReactDOM from 'react-dom';
//A组件,组件要求大写字母开头
import A from './App';
ReactDOM.render(<A />, document.getElementById('root'));
函数组件和class组件的区别
用构造函数创建出来的组件,叫做“无状态组件”;
用class关键字创建出来的组件,叫做“有状态组件”;
有状态组件和无状态组件之间的本质区别是有无state属性。
注意:
使用class 关键字创建的组件,有自己的私有数据(this.state)和生命周期函数;
使用function创建的组件,只有props,没有自己的私有数据和生命周期函数;
3、props属性
react中说的单向数据流值说的就是props,根据这一特点它还有一个作用:组件之间的通信。
props属性的特点:
-
每个组件对象都会有props(properties的简写)属性
-
组件标签的所有属性都保存在props中
-
内部读取某个属性值:this.props.propertyName
-
作用:通过标签属性从组件外 向组件内传递数据(只读 read only)
-
对props中的属性值进行类型限制和必要性限制
代码示例
使用函数组件:
import React from 'react';
import ReactDOM from 'react-dom';
//使用函数组件
function User(props){
//在组件中获取props属性值
return <div>{props.name},{props.age}</div>
}
//定义数据
const person ={
name:'张三',
age:20,
sex:'男'
}
ReactDOM.render(
<User {...person}></User>
, document.getElementById('root'));
使用类组件:
import React from 'react';
import ReactDOM from 'react-dom';
//使用class组件
class User extends React.Component{
render(){
return (
<div>{this.props.name}--{this.props.age}</div>
);
}
}
//数据
const person ={
name:'张三',
age:20,
sex:'男'
}
ReactDOM.render(
<User {...person}></User>
, document.getElementById('root'));
4、state 属性
React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
代码示例:
import React from 'react';
import ReactDOM from 'react-dom';
class Person extends React.Component{
//构造方法
constructor(){
super();
this.state = {
name: 'tom'
}
}
render(){
//state属性是可修改的
this.state.name = 'jack';
return (
<h1>{this.state.name}</h1>
);
}
}
ReactDOM.render(<Person />, document.getElementById('root'));
设置状态:setState
setState(object nextState[, function callback])
不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。
setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑
5、props和state属性的区别
- props中的数据都是外界传递过来的;
- state中的数据都是组件私有的;(通过Ajax获取回来的数据,一般都是私有数据)
- props中的数据都是只读的,不能重新赋值;
- state中的数据,都是可读可写的;
- 子组件只能通过props传递数据;
6、父组件传值子组件
完整示例:
创建父组件 index.js
import React from 'react';
import ReactDOM from 'react-dom';
import User from './User';//引入子组件
//定义数据
const person = {
name: 'Tom',
age:20
}
ReactDOM.render(
//渲染子组件,并向子组件传递name,age属性
<User name={person.name} age={person.age}></User>
, document.getElementById('root'));
创建子组件 User.js
import React from 'react';
class User extends React.Component{
render(){
return (
// 使用props属性接收父组件传递过来的参数
<div>{this.props.name},{this.props.age}</div>
);
}
}
export default User;
index.js文件
ReactDOM.render(
//渲染子组件,并向子组件传递name,age属性
<User {...person}></User>
, document.getElementById('root'));
User.js
render(){
return (
// 使用props属性接收父组件传递过来的参数
<div>{this.props.name},{this.props.age}</div>
);
}
7、子组件传值父组件
子组件通过调用父组件传递到子组件的方法向父组件传递消息的。
完整案例
子组件 Son.js 文件代码示例:
import React from 'react';
class Son extends React.Component {
//构造方法
constructor(){
super();
this.state = {
inputValue:''
}
}
//按钮点击事件
handleClick(){
//通过props属性获取父组件的getdata方法,并将this.state值传递过去
this.props.getdata(this.state.inputValue);
}
//输入框事件,用于为this.state赋值
handleChange(e){
this.setState({
inputValue: e.target.value
});
}
render(){
return (
<React.Fragment>
<input onChange={this.handleChange.bind(this)}></input>
<button onClick={this.handleClick.bind(this)}>点击获取数据</button>
</React.Fragment>
);
}
}
export default Son;
父组件 Parent.js 文件代码示例:
import React from 'react';
import Son from './Son';
class Parent extends React.Component {
//构造方法
constructor(){
super();
this.state = {
mess: '' //初始化mess属性
}
}
//用于接收子组件的传值方法,参数为子组件传递过来的值
getDatas(msg){
//把子组件传递过来的值赋给this.state中的属性
this.setState({
mess: msg
});
}
render(){
return (
<React.Fragment>
{/* 渲染子组件,设置子组件访问的方法,
getdata属性名为子组件中调用的父组件方法名 */}
<Son getdata={this.getDatas.bind(this)}></Son>
<div>展示数据:{this.state.mess}</div>
</React.Fragment>
);
}
}
export default Parent;
入口文件 index.js示例代码:
import React from 'react';
import ReactDOM from 'react-dom';
import Parent from './Parent';
ReactDOM.render(<Parent></Parent>, document.getElementById('root'));
8、兄弟组件传值
兄弟组件之间的传值,是通过父组件做的中转 ,流程为:
**组件A **-- 传值 --> 父组件 – 传值 --> 组件B
完整案例
创建 Acls.js 组件,用于提供数据
import React from 'react';
class Acls extends React.Component {
//按钮点击事件,向父组件Pcls.js传值
handleClick(){
this.props.data("hello...React...");
}
render(){
return (
<button onClick={this.handleClick.bind(this)}>Acls组件中获取数据</button>
);
}
}
export default Acls;
创建父组件 Pcls.js 用于中转数据
import React from 'react';
import Acls from './Acls';
import Bcls from './Bcls';
class Pcls extends React.Component {
//构造函数
constructor(){
super();
this.state = {
mess: ''
}
}
//向子组件Acls.js提供的传值方法,参数为获取的子组件传过来的值
getDatas(data){
this.setState({
mess: data
});
}
render(){
return (
<React.Fragment>
Pcls组件中显示按钮并传值:
<Acls data={this.getDatas.bind(this)}></Acls>
<Bcls mess={this.state.mess}></Bcls>
</React.Fragment>
);
}
}
export default Pcls;
创建子组件 Bcls.js 用于展示从 Acls.js 组件中生成的数据
import React from 'react';
class Bcls extends React.Component {
render(){
return (
<div>在Bcls组件中展示数据:{this.props.mess}</div>
);
}
}
export default Bcls;