箭头函数
下面很多时候都会出现 => 这样子的东西 这个不是大于等于 而是es6的一个语法糖箭头函数 它的用处很多 最大的用处就是关于this的绑定 这个慢慢体会就好 在此不做详细解释 下面可能会出现的几个箭头函数用法作说明:
//不带参数的箭头函数
const handleClick = () => {
console.log(123);
}
<Button onClick={this.handleClick}>dianwo</Button>
// 带参数的箭头函数
const handleClick = (value) => () => {
console.log(value)
}
<Button onClick={this.handleClick('hai')}>dianwo</Button>
上面的写法等效于
const handleClick = (value) => {
console.log(value)
}
<Button onClick={() => this.handleClick('hai')}>dianwo</Button>
React类组件
类组件的模版
class DemoComponent extends React.Component {
state = {
}
render() {
return (
<div>
HelloWorld!!
</div
)
}
}
state
state是类组件自己维护的状态属性 定义后不可通过访问对象的方式去更改 要通过setState函数更改 setState后页面的刷新不是同步的
例如
class DemoComponent extends React.Component {
state = {
name: '123',
}
render() {
return (
<div>
{this.state.name}
</div
)
}
}
这个例子会显示123这个名字 但如果我们想点击按钮更改state的name就需要 PS: 这里用到了es6的箭头函数
class DemoComponent extends React.Component {
state = {
name: '123',
}
handleNameChange = () => {
this.setState({
name: 'heiheihei',
})
}
render() {
return (
<div>
{this.state.name}
<button onClick={this.handleNameChange}>changeName</button
</div>
)
}
}
当点击按钮后123就会变成heiheihei
上面只是一个简单的例子去介绍类组件的state的用法 state的作用一般用于:
- 某个组件或者页面他需要独立去维护某种状态或者数据的时候
- 接受props的数据但需要在该组件内去更改这个props的值(仅仅是在该组件内,对父组件无影响)
props
当编写好一个类组件后 通常需要配合其他组件的使用组合成一个页面 比如我写了一个简单的计算器组件CalComponent PS: React.PureComponenet和React.Compoenent区别
// CalComponent.jsx
import React from 'react';
import { Input, Button } from 'antd';
import PropTypes from 'prop-types';
class CalComponent extends React.PureComponent {
static propTypes = {
type: PropTypes.string.isRequired
title: PropTypes.string,
}
static defaultProps = {
title: '默认',
}
state = {
value1: '',
value2: '',
result: null,
}
handleInputChange = (keyName) => ({ target }) => {
this.setState({
[keyName]: target.value,
})
}
handleCalcClick = () => {
let result;
const { type } = this.props;
if(type === 'add') {
result = this.state.value1 + this.state.value2;
} else if ( type === 'multipy') {
result = this.state.value1 * this.state.value2;
} else if ( type === 'divide') {
result = this.state.value1 / this.state.value2;
} else if ( type === 'minus') {
result = this.state.value1 - this.state.value2;
}
this.setState({
value1: '',
value2: '',
result,
})
}
render() {
return (
<div>
{this.props.title}
<Input
value={this.state.value1}
onChange={this.handleInputChange('value1')}
/>
<Input
value={this.state.value2}
onChange={this.handleInputChange('value2')}
/>
<Button onClick={this.handleCalcClick}>计算</Button>
{this.result && <div>
结果:{this.state.result}
</div>}
</div>
)
}
}
export default CalComponent;
// IndexView.jsx
import React from 'react';
import CalComponent from './CalComponent.jsx';
class IndexView extends React.PureComponenet {
state = {
type: null,
}
handleTypeChange = (value) => {
this.setState({
type: value,
})
}
render() {
return (
<div>
<Button
onClick={() => this.handleTypeChange()}
>加法</Button>
<Button
onClick={() => this.handleTypeChange()}
>减法</Button>
<Button
onClick={() => this.handleTypeChange()}
>乘法</Button>
<Button
onClick={() => this.handleTypeChange()}
>除法</Button>
{this.state.type && <CalComponent type={this.state.type} />}
</div>
)
}
}
生命周期 (参考自官网)
创建组件的时候会经历一系列的生命周期,生命周期就是一个组件从有到无再到无的过程。
周期顺序一般为 挂载——更新——卸载
挂载
当组件实例被创建并插入DOM时,生命周期会如以下顺序调用:
- constructor()
- static getDerivedStateFromProps()
- render()
- componentDidMount()
更新
当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:
- static getDerivedStateFromProps()
- shouldComponentUpdate()
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
卸载
当组件从DOM中移除时会调用如下方法:
- componentWillUnmount()
错误处理
当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:
- static getDerivedStateFromError()
- componentDidCatch()
具体说明
constructor()
避免将 props 的值复制给 state!
constructor(props) {
super(props);
this.state = {
counter: 0
};
this.handleClick = this.handleClick.bind(this);
}
componentDidMount()
componentDidMount() 会在组件挂载后(插入 DOM 树中)立即调用。
依赖于 DOM 节点的初始化应该放在这里。
如需通过网络请求获取数据,此处是实例化请求的好地方。
这里面也可以添加订阅,但要在 componentWillUnmount() 里取消订阅
这里面也可以调用 setState() 方法,会进行额外的渲染,发生在浏览器更新屏幕前。
在里面过多使用 setState 会造成性能问题
componentDidUpdate()
componentDidUpdate() 会在更新后会被立即调用 首次渲染不会执行此方法
当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。
componentDidUpdate(prevProps) {
// 典型用法(不要忘记比较 props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
componentWillUnmount()
componentWillUnmount() 会在组件卸载及销毁之前直接调用。
在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。
componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。
组件实例卸载后,将永远不会再挂载它。
static getDerivedFromStateToProps(state, props)
getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。
每次渲染前触发此方法</b
函数组件
函数组件就是用Function的方式去构建所有的组件,万物皆Func 注意:!!函数组件又称为无状态组件,与之对应的是有状态组件(类组件) 顾名思义,无状态就是说他没有state去独立的管理这个组件的内部状态,只有靠外部的props去传递参数改变他的状态。 例子:
const AddComponent = (props) => {
const { a, b } = props;
return <div>{ a + b }<div>
}
*通过HOOKS实现有状态的函数式写法
import { useState, useEffect } from 'react';
import { Button } form 'antd';
const CalcComponent = (props) => {
useEffect(() => { // 用来代替生命周期
// componentDidMount,componentDidUpdate 和 componentWillUnmount的组合
}, []) // 第二个参数为触发条件
const [type, setType] = useState(null);
const handleTypeChange = (mode) => {
setType(mode);
}
return <div>
{type}
<Button onClick={() => handleTypeChange('状态1')}>改变状态1</Button>
<Button onClick={() => handleTypeChange('状态2')}>改变状态1</Button>
<Button onClick={() => handleTypeChange('状态3')}>改变状态1</Button>
</div>
}
父子组件通讯
众所周知 在React里数据流是单向的,从上至下传递,子组件获取到父组件的值后,并不能通过对象或者属性方法直接修改父组件的值,也就是说,子组件干了什么父组件是不知道的,那子组件如何告知父组件自己干了什么,这时候就需要父组件去定义一个函数然后当作props传递给子组件 子组件通过这个函数去修改父组件的属性 例子:
// 父组件
Class FatherComponent extends React.PureComponent {
state = {
status: false,
}
handleStatusChange = () => {
this.setState({
status: !this.state.status,
})
}
render() {
return(
<SonComponent
onStatusChange={this.handleStatusChange}
status={this.state.status}
/>
)
}
}
//子组件
Class SonComponent extends React.PureComponent {
static propTypes = {
status: PropTypes.boolean.isRequired,
onStatusChange: PropTypes.func.isRequired,
}
render() {
return(
<div>
{this.props.status ? '真' : '假'}
<Button onClick={this.props.onStatusChange}>我要改变父组件!!!</Button>
</div>
)
}
}