React高阶组件强制重新渲染被包装的组件

React Higher Order Component forces re-render of wrapped component

本文关键字:组件 包装 新渲染 高阶 React      更新时间:2023-09-26

我正在努力理解如何在高阶组件中正确实现此验证行为。

===========================================

编辑:TLDR:感谢用户@noa-dev的优秀建议,我在这里创建了一个React Fiddle: https://jsfiddle.net/8nLumb74/1/来显示这个问题。

简单地说:为什么我的文本框在这个HOC包装时失去了编辑的重点?

我做错了什么?

Textbox组件:

import React from 'react'
export default React.createClass({
    changeText(e) {
        if (this.props.validate)
            this.props.validate(e.target.value)
        this.props.update(e.target.value)
    },
    componentDidMount() {
        console.log('should only be fired once')
    },
    render() {
        return (<input type="text"
            value={this.props.text}
            onChange={this.changeText} />)
    }
})

Validator组件:

import React from 'react'
export default function (WrappedComponent) {
    const Validation = React.createClass({
        validate(text) {
            console.log('validating', text)
        },
        render() {
            return (
                <WrappedComponent
                {...this.props}
                validate={this.validate}
                />
            )
        }
    })
    return Validation
}

父Form组件:

import React from 'react'
import TextBox from './text-box'
import Validator from './validator'
export default React.createClass({
    getInitialState() {
        return ({text: 'oh hai'})
    },
    update(text) {
        this.setState({text})
    },
    render() {
        const ValidatingTextBox = Validator(TextBox)
        return (<ValidatingTextBox
            text={this.state.text}
            update={this.update} />)
    }
})

Form组件的render方法中,每次都创建一个新的ValidatingTextBox:

    render() {
        const ValidatingTextBox = Validator(TextBox)
        return (<ValidatingTextBox
            text={this.state.text}
            update={this.update} />)
    }
相反,您应该创建组件,然后使用它来维护实例。可能的Form组件如下所示:
import React from 'react'
import TextBox from './text-box'
import Validator from './validator'
const ValidatingTextBox = Validator(TextBox) 
export default React.createClass({
    getInitialState() {
        return ({text: 'oh hai'})
    },
    update(text) {
        this.setState({text})
    },
    render() {
        return (<ValidatingTextBox
            text={this.state.text}
            update={this.update} />)
    }
})