1. React生命周期使用场景
    1. 只会调用一次
    2. 多次调用

React生命周期使用场景

版本:v16.10.2

只会调用一次

  • constructor(props)

    初始化state

    修正指向

    class Demo extends React.Component {
        constructor(props) {
            super(props);
            this.state = {  //初始化state
                msg: "click"
            }
            this.onClickHandle = this.onClickHandle.bind(this);  //修正指向
        }
    
        onClickHandle(e) {
            console.log('handle',this);
        }
    
        render() {
            console.log('render');
            return (
                <a onClick={this.onClickHandle}>{this.state.msg}</a>
            );
        }
    }
  • componentDidMount()

    发起请求加载数据

    发起订阅(定时器、emmiter等)

    class Demo extends React.Component {
        componentDidMount() {
            Emitter.on('start',() => {  //自定义事件订阅
                console.log('start');
            });
        }
    
        componentWillUnmount() {
            Emitter.off('start');
        }
    
        render() {
            console.log('render');
            Emitter.emit('start');
    
            return (
                'demo'
            );
        }
    }
    
    function addTimer(Component) {  //定时器
        let timer = null;
    
        return class extends React.Component {
            componentDidMount() {
                timer = setInterval(() => {
                    console.log('timer');
                },1000);
            }
    
            componentWillUnmount() {
                clearInterval(timer);
            }
    
            render() {
                return (
                    <Component />
                )
            }
        }
    }
    
    const DemoWithTimer = addTimer(Demo);
  • componentWillUnmount()

    解绑定时器

    卸载事件

多次调用

  • static getDerivedStateFromProps(nextProps, nextState),需要返回类似setState的第一个参数值

    props变化时更新state

    用于自定义受控组件,如Upload回填数据

    //Upload引用自antd
    //注意以下state初始化方法需要babel plugin
    class UploadFile extends React.Component {
        state = {
            loading: false,
            isEmpty: true,
            fileUrl: ""
        };
    
        static getDerivedStateFromProps(nextProps, nextState) {
              if (this.props.value !== nextProps.value) {
                return {
                    fileUrl: nextProps.value,
                }
            }
        }
    
        handleChange = info => {
            const { onChange } = this.props;
            if(info.file.status === 'uploading') {
                this.setState({
                    loading: true,
                })
            }
            if(info.file.status === 'done') {
                const { fileUrl } = info.file.response ? info.file.response.data : {};
                this.setState({
                    fileUrl: fileUrl,
                    isEmpty: false,
                })
                onChange(fileUrl);
            }
            if(info.file.status === 'error') {
                message.error('上传接口出现问题!');
            }
            this.setState({
                loading: false,
            });
        }
    
        handleDelete = () => {
            const { onChange } = this.props;
            const { confirm } = Modal;
            const self = this;
    
            confirm({
                title: '提示',
                content: '确认删除吗?',
                okText: '是',
                cancelText: '否',
                onOk() {
                    self.setState({
                        fileUrl: "",
                        isEmpty: true,
                    })
                    onChange && onChange("");
                },
                onCancel() {},
            });
        }
    
        render() {
            const { fileUrl } = this.state;
            const {
                onChange,
                  ...others
            } = this.props;
    
            return (
                <div>
                    <Upload
                        onChange={this.handleChange}
                          { ...others }>
                            <Button>
                                <Icon type={this.state.loading ? 'loading' : 'upload'} />
                                { this.state.isEmpty ? '上传文件': '重新上传' }
                            </Button>
                    </Upload>
                    {
                        fileUrl ?
                            (
                            <span>
                                <a className="upload-url" target="_blank" href={fileUrl} alt={fileUrl}>文件链接</a>
                                <Icon type="close" className="delete-pic" onClick={this.handleDelete}/>
                            </span>
                            )
                            : null
                    }
                </div>
            )
        }
    }

    动画组件更新起始、目标或其他动画参数值(同理,不再书写示例)

  • shouldComponentUpdate(nextProps,nextState)

    性能优化,判断组件是否需要render

    涉及这方面的需求属于特殊情况,一般会使用React.PureComponent代替这种方案

  • render()

  • getSnapshotBeforeUpdate(preProps,preState),可选返回值作为componentDidUpdate的第三个参数,不返回则为null

    UI控制,参考官方文档示例

  • componentDidUpdate(prevProps,prevState,snapshot)

    动画组件执行、操作dom