React js - 禁用mixin中组件的渲染

时间:2014-12-01 10:56:17

标签: javascript mixins reactjs

我正在尝试开发一个React mixin来在渲染组件之前检查用户访问级别。

如果用户没有查看组件的权限,我想禁用组件的呈现。 我一直在寻找能够处理这个但没有发现的东西,所以我做到了:

var AuthentLevelMixin = {
    componentWillMount: function() {
        if(!Auth.check()) {
            // Disable component render method
            this.render = function () {
                return false;
            }
        }
    }
}

它按预期工作,但我觉得这是“肮脏的方式”。

所以我的问题是:与此片段相同的“反应方法”是什么?

3 个答案:

答案 0 :(得分:5)

对于mixin来说,这是你能做的最好的事情。它只是渲染中的一个简单的早期回归。

var AuthentLevelMixin {
  isAuthenticated: function(){
    return Auth.check();
  }
};

var C = React.createClass({
    mixins: [AuthentLevelMixin],
    render: function(){
      if (!this.isAuthenticated()) return <div />;
      return (
         <div>...</div>
      );
    }
});

如果您决定采用初始策略(我不推荐),只需稍加修改即可:

// more explicit names are important for dirty code
var PreventRenderUnlessAuthMixin = {
    componentWillMount: function() {
        this._originalRender = this.render;
        this._setRenderMethod();
    },
    componentWillUpdate: function(){
        this._setRenderMethod();
    }.

    _emptyRender: function () {
        return <span />;
    },
    _setRenderMethod: function(){
        this.render = Auth.check() ? this._originalRender : this._emptyRender;
    }
}

答案 1 :(得分:3)

如果您想在mixin中处理授权而不向组件添加逻辑,那么您正在以正确的方式执行此操作。但是:实现这个mixin的每个组件都应该知道这个mixin中发生了什么。如果你期望的结果是,没有任何东西被渲染,那么你对你正在做的事情是完全正确的。因此,如果你的方式导致简单,那就是React-Way。在我的意见中就是这种情况。

在componentWillMount生命周期事件中,您将在渲染之前捕获瞬间 - 这是防止渲染的好时机。所以我真的没有看到任何反对你的代码的事情。

编辑:

定义的方法:&#34;反应方式&#34;

一旦你有相同的输入,每次代码变得可预测时产生相同的输出。您的代码可以预测,您可以实现简单性。这些是Pete Hunt用来描述React意图的术语。因此,如果你保持可预测性并且在结果上实现简单,你就是以反应的方式做到这一点。

如果是上述混合,则这两条规则都适用,因此&#34;反应方式&#34;在我上面提供的定义中。

答案 2 :(得分:0)

我的建议是不要使用mixin。清理组件的最佳方法是从组件中删除此逻辑,而不是根据检查Auth的结果呈现组件。

这个问题是你有一个不再一致的组件,因为它取决于其道具以外的东西。除了向上推动问题之外,这并没有什么用处,但它确实允许你有一个更纯的组件。

我可以看出为什么mixin很有吸引力,所以这里有一个更简单的方法来做你需要的,不涉及动态交换渲染方法:

var PreventRenderUnlessAuthMixin = {
  componentWillMount: function () {
    var oldRender = this.render;
    this.render = function () {
      return Auth.check() ? this.render() : <div />
    }.bind(this);
  }
}