[React组件封装][实例]不受控组件变成受控组件

公众号:程序员波波

[React组件封装][实例]不受控组件变成受控组件

开发中可能会用到一些第三方的组件或者是早期开发的组件,而这些组件并不受控。就是说组件内部维护了state或者内部修改了一下数据,导致组件的状态并不是由props来定义的。

所以我们希望通过封装一层,来使得组件变得受控。

步骤:

1、首先我们需要知道组件的状态是由哪些变量定义的。(比如富文本的状态是由富文本的内容定义的)

2、然后封装一层受控组件,受控组件通过props来控制组件。

3、受控组件需要区分两种行为。第一种是外部组件通过props的直接修改,来改变状态。第二种是内部组件自己修改状态,触发onChange来告诉外部组件修改props。第一种情况下,受控组件肯定需要手动改变组件的状态,来符合props。第二种情况下,其实是不需要更新组件的,因为组件已经是在onChange触发的状态下。

以富文本从不受控到受控为例:

有一个富文本组件RichEditor,它本身不受控,它内部维护了一个state。外部可以通过setData来改变状态,通过getData来获得状态。

那么封装一层RichEditorControl,它拥有一个last_data变量存储当前的状态。那么如果props中的data与last_data不等,需要通过setData改变富文本的状态,如果富文本内容主动修改了,那么需要更新last_data。这种情况下,在下一次componentDidUpdate的时候,last_data和props.data是相等的,并不会触发更新。

代码:

import React, { PureComponent } from 'react';
import RichEditor from './RichEditor';

class RichEditorControl extends PureComponent {
    constructor(props) {
        super(props)

        this.last_data = null
        this.onChange = this.onChange.bind(this)
    }

    onChange() {
        this.last_data = this.refs.richeditor.getData()
        if (this.props.onChange) {
            this.props.onChange(this.last_data)
        }
    }

    resetData() {
        const {data} = this.props
        if (data != this.last_data) {
            if (data) {
                this.refs.richeditor.setData(data)
            }
            this.last_data = data
        }
    }

    componentDidMount() {
        this.resetData()
    }

    componentDidUpdate() {
        this.resetData()
    }

    render() {
        const {data} = this.props
        return (
            <RichEditor
                {...this.props}
                ref='richeditor'
                key={data ? 'notempty' : 'empty'}
                onChange={this.onChange}
            />
        )
    }
}

export default RichEditorControl

 

上一篇:input的几种触发事件


下一篇:HashMap和TreeMap的区别