reactjs - 使用 HOC 组件 React 重建树(导致输入字段焦点丢失)

标签 reactjs

我正在使用高阶组件来装饰我的组件。

const HOC = (WrappedComponent) => (props) => {
    return (
        <span>
            <p>HOC Comp</p>
            <WrappedComponent {...props}/>
        </span>
    )
}

我确实喜欢这里解释的这种模式:React Higher Order Components in depth

但是我有一个问题,因为 HOC 导致 React 重新创建我的组件树而不是更新树。这在这里得到了很好的解释React Reconciliation 。 HOC 返回一个匿名函数,React 不知道它实际上正在渲染相同的组件。这对性能不利,并使我的输入字段失去焦点。

如何使用 HOC 组件而不用 React 在每个 render() 上重新创建我的树?

示例代码:

class Input extends React.Component {
    componentWillMount() {
        console.log('input component will mount');
    }

    componentWillUnmount() {
        console.log('input component will unmount');
    }

    render() {
        return (
            <span>
                <input value={this.props.value} onChange={this.props.onChange}/>
            </span>
        );
    }
}

const HOC = (WrappedComponent) => {
    const Help = (props) => {
        return (
            <span>
                <WrappedComponent {...props}/>
                <p>{props.help}</p>
            </span>
        )
    };

    return Help;
}

class MyComponent extends React.Component {
    constructor (props) {
        super(props);
        this.state = {value : 'start value'}
    }

    onChange(event) {
        this.setState({value : event.target.value});
    }

    render() {
        const Element = HOC(Input);
        return (
            <span>
                <Element
                    value={this.state.value}
                    onChange={this.onChange.bind(this)}
                />
            </span>
        )
    }
}

ReactDOM.render(
    <MyComponent />,
    document.getElementById('container')
);

参见Fiddle example (每次更改输入并失去焦点时,请在浏览器的控制台中查看输入组件的安装和卸载日志)

最佳答案

您不必在渲染函数中创建Element。相反,您可以在构造函数中创建它:

class MyComponent extends React.Component {
    constructor (props) {
        super(props);
        this.state = {value : 'start value'};
        this.element = HOC(Input);
    }
...

并在渲染函数中使用它,如下所示:

        <span>
            <this.element
                value={this.state.value}
                onChange={this.onChange.bind(this)}
            />
        </span>

如果需要,您可以在 componentWillReceiveProps()componentWillUpdate() 中更新 this.element

更新:fiddle

关于reactjs - 使用 HOC 组件 React 重建树(导致输入字段焦点丢失),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40590515/

相关文章:

javascript - 使用 flexbox 垂直对齐内容

javascript - react Hook : old state value persisting in closure

javascript - 在 addEventListener 上 react typescript 问题

javascript - 如何对 API 调用进行单元测试并断言 React 和 Enzyme 中的状态更改?

javascript - React 和 Material-ui - 凸起按钮 - 如何实现始终禁用单击的按钮?

reactjs - 如何使 React 在整个应用程序上可用,而无需在每个 jsx 文件中一次又一次地导入它

javascript - 如何在 React JS 中解析 Json 对象数组

javascript - 排序方法及索引

javascript - 测试时 React props 函数未定义

javascript - ReactJS 可以在 Bootstrap 中返回 div 吗?