【问题标题】:Extending Components with React Router使用 React Router 扩展组件
【发布时间】:2016-10-10 09:54:21
【问题描述】:

假设我有一个带有一些 React Router 导航的 Foo 组件:

var Foo = React.createClass({
    render: function() {
        return (<div>
            <Link to="/foo/1">1</Link>;
            <Link to="/foo/2">2</Link>;
            {this.props.children}
        </div>);
    }
});
var Foo1 = React.createClass({
    render: function() {
        return <p>foo 1</p>;
    }
});
var Foo2 = React.createClass({
    render: function() {
        return <p>foo 2</p>;
    }
});
ReactDOM.render((
    <Router>
        <Route path="/" ...>
            <Route path="foo" component={Foo}>
                <Route path="1" component={Foo1} />
                <Route path="2" component={Foo2} />
            </Route>
        </Route>
    </Router>
), document.getElementById('main'));

现在假设我也有一个 Bar 组件,它非常相似(除了 bar 而不是 foo)。在“经典”的 React 应用程序中,我会“提取”出通用逻辑,如下所示:

var Element = React.createClass({
    render: function() {
        return (<div>
            <Link to={this.props.url + '/1'}>1</Link>;
            <Link to={this.props.url + '/2'}>2</Link>;
            {this.props.children && React.cloneElement(this.props.children {
                name: this.props.name // Ugly hack to propagate props...
            })}
        </div>);
    }
});
var Element1 = React.createClass({
    render: function() {
        return <p>{this.props.name} 1</p>;
    }
});
var Element2 = React.createClass({
    render: function() {
        return <p>{this.props.name} 2</p>;
    }
});
var Foo = React.createClass({
    render: function() {
        return <Element url="/foo" name="foo" />;
    }
});
var Bar = React.createClass({
    render: function() {
        return <Element url="/bar" name="bar" />;
    }
});

如您所见,我几乎得到了它(即使是丑陋的道具传播黑客......)。我缺少的部分是如何定义路由本身:

ReactDOM.render((
    <Router>
        <Route path="/" ...>
            <Route path="foo" component={Foo}>
                <Route path="1" component={?} />
                <Route path="2" component={?} />
            </Route>
        </Route>
    </Router>
), document.getElementById('main'));

我的意思是,不再有 Foo1Foo2 组件,因为 Foo 有一个 Element,它们通常是从中派生的。当然,我可以明确定义Foo1 以拥有Element1Foo2 以拥有Element2,但是我必须实现Foo 而不是让Element 为我做这件事;或者我可以将组件本身作为道具传递(即Foo = ... &lt;Element ... component1={Foo1} component2={Foo2} /&gt;...但是然后呢?)。

那么:我如何在启用 React Router 的情况下实现这种 React-ious “通过组合继承”?还是有其他方法可以做到这一点?

【问题讨论】:

    标签: reactjs react-router


    【解决方案1】:

    我想到了一个解决方案,所以我想我会把它发布给有类似问题的人。请注意,我对此还是新手..呃..“心态”,所以这可能不是最好的方法。

    事情是这样的:foo/bar 的差异(url="/foo|/bar"name="foo|bar")可以“汇总”到单个 "foo|bar" 标记中,然后可以将其作为 参数提取到 URL 中时间>。那就是:

    ReactDOM.render((
        <Router>
            <Route path="/" ...>
                <Route path="/:tag" component={Element}>
                    <Route path="/:tag/1" component={Element1} />
                    <Route path="/:tag/2" component={Element2} />
                </Route>
            </Route>
        </Router>
    ), document.getElementById('main'));
    

    并且可以重写元素以考虑该标签:

    var Element = React.createClass({
        render: function() {
            return (<div>
                <Link to={'/' + this.props.params.tag + '/1'}>1</Link>;
                <Link to={'/' + this.props.params.tag + '/2'}>2</Link>;
                {this.props.children}
            </div>);
        }
    });
    var Element1 = React.createClass({
        render: function() {
            return <p>{this.props.params.tag} 1</p>;
        }
    });
    var Element2 = React.createClass({
        render: function() {
            return <p>{this.props.params.tag} 2</p>;
        }
    });
    

    就是这样!您甚至不需要&lt;Foo /&gt;&lt;Bar /&gt; 组件。

    我对这个解决方案不太满意的原因是它适用于足够简单的情况(比如这个例子,或者我正在处理的实际 CMS),但我不确定它是否可以扩展到更复杂的情况设计;这就是 URL 冲突:必须首先出现带有 &lt;Baz /&gt; 组件的 /baz 路由,否则将评估带有 "baz" 标签的 &lt;Element /&gt;。我还没有找到如何使用 React Router 定义复杂的参数(如正则表达式),但如果我这样做了,我会更新答案。

    【讨论】:

      猜你喜欢
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 2022-06-18
      • 2020-06-03
      • 2021-06-09
      • 2016-11-03
      • 2016-06-11
      • 2018-01-07
      相关资源
      最近更新 更多