您如何在React中实现高阶组件?

时间:2019-05-25 20:08:07

标签: javascript reactjs ecmascript-6

我正在尝试在React中设置一个HOC,以便能够将文本选择检测应用于任何Input组件。但是,当我尝试将它们放在一起时,似乎似乎缺少了一些东西。

我在这里关注如何创建HOC:

https://levelup.gitconnected.com/understanding-react-higher-order-components-by-example-95e8c47c8006

我的代码(在文章看起来像这样之前):

import { func } from 'prop-types';
import React, { PureComponent } from 'react';
import { Input } from 'reactstrap';

class SelectableInput extends PureComponent {
    handleMouseUp = () => {
        const selection = window.getSelection();

        if (selection) {
            this.props.onSelectionChanged(selection.toString());
        }
    };

    render() {
        // eslint-disable-next-line
        const { onSelectionChanged, ...rest } = this.props;
        return <Input onMouseUp={this.handleMouseUp} {...rest} />;
    }
}

SelectableInput.propTypes = {
    onSelectionChanged: func
};

export default SelectableInput;

我正在这样使用它:

    render() {
        return (
                <SelectableInput
                    type="textarea"
                    name="textarea-input"
                    value={'This is some txt'}
                    onSelectionChanged={onTextSelectionChanged}
                    id="textarea-input"
                    onChange={e => this.onPageDataChanged(e)}
                    dir="rtl"
                    rows="14"
                    placeholder="Placeholder..."
                />
        );
    }

阅读文章后,我将上面的代码更改为:

const SelectableInput = WrappedInput => {
    class SelectableInputHOC extends PureComponent {
        handleMouseUp = () => {
            const selection = window.getSelection();

            if (selection) {
                this.props.onSelectionChanged(selection.toString());
            }
        };

        render() {
            // eslint-disable-next-line
            const { onSelectionChanged, ...rest } = this.props;
            return <WrappedInput onMouseUp={this.handleMouseUp} {...rest} />;
        }
    }

    SelectableInputHOC.propTypes = {
        onSelectionChanged: func
    };
};

export default SelectableInput;

我的问题是,现在我该如何实际在render()函数中使用它?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

SelectableInput是一个函数,该函数返回以组件为参数并返回另一个组件的函数。您可以像这样使用它:

const ResultComponent = ({...props}) =>
    SelectableInput({...props})(YourParamComponent);

然后在任意位置渲染ResultComponent。

这里有一个使用HOC并将道具传递给它的示例:

https://jsfiddle.net/58c7tmx2/

HTML:

<div id="root"></div>

JS

const YourParamComponent = ({ name }) => <div>Name: {name}</div>

const SelectableInput = ({...props}) =>
    WrappedInput => <WrappedInput {...props} />

const ResultComponent = ({...props}) =>
    SelectableInput({...props})(YourParamComponent);

const App = () => <ResultComponent name="textarea-input" />

ReactDOM.render(
    <App />,
    document.getElementById('root')
)
相关问题