React组件类元编程

时间:2014-09-19 20:56:11

标签: javascript metaprogramming reactjs react-bootstrap

我正在使用React并使用React-Bootstrap组件。

我在React-Bootstrap库中发现了一些问题,我通过编辑react-bootstrap.js文件来“修复”(或“修改”)。问题是,如果明天会出现一个新版本的react-bootstrap,那么我将不得不将我在react-bootstrap.js文件中编写的所有代码复制粘贴/重写/写入新版本。我不想这样做,所以如果有一种方法来修改react-bootstrap提供的组件类(即更改渲染函数)而不触及react-bootstrap.js文件,我就会徘徊。问题是我无法弄清楚如何做到这一点,或者至少我发现组件类的内部工作并不容易理解。关于如何实现这一点的任何想法?

提前致谢!

1 个答案:

答案 0 :(得分:1)

你可以使用一个包装组件,在它安装后覆盖原始组件的方法:

    function wrapComponent (originalComponent, override) {
        return React.createClass({
            componentDidMount: function () {
                for (var property in override) {
                    if (override.hasOwnProperty(property)) {
                        this.refs.original[property] = override[property];
                    }
                }
            },
            render: function () {
                return this.transferPropsTo(
                    <originalComponent ref="original">{ this.props.children }</originalComponent>
                );
            }
        });
    }

    var ConsoleSample = React.createClass({
        // This method can still be used:
        prefix: function (text) {
            return "prefix: " + text;
        },
        // This method will be overridden:
        output: function (text) {
            console.log(this.prefix(text));
        },
        onClick: function () {
            this.output("Hello world");
        },
        render: function () {
            return <button onClick={this.onClick}>{ this.props.children }</button>
        }
    });

    var Application = React.createClass({
        render: function () {
            var AlertSample = wrapComponent(ConsoleSample, { 
                output: function (text) {
                    alert(this.prefix(text));
                }
            });
            return <div>
                <ConsoleSample>This should console.log</ConsoleSample>
                <AlertSample>This should alert</AlertSample>
            </div>
        }
    });

    React.renderComponent(<Application />, document.body.lastChild);

虽然这是一个简单的黑客攻击。我同意正确的解决方案是分叉React-Bootstrap。