React js - 禁用混合中组件的渲染

React js - Disable render of a component in a mixin

本文关键字:组件 混合 js React      更新时间:2023-09-26

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

如果用户没有查看组件的权限,我想禁用组件的呈现。我一直在寻找 react 中内置的东西来处理这个问题,但一无所获,所以我这样做了:

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

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

所以我的问题是:与这个片段做同样的事情的"反应方式"是什么?

对于混音来说,这是你能做的最好的事情。 这只是渲染中的简单早期返回。

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;
    }
}

如果你想在不向组件添加逻辑的情况下处理 mixin 内部的授权,那么你就是以正确的方式去做的。但是:实现此mixin的每个组件都应该知道此mixin中发生了什么。如果你期望的结果是,什么都没有渲染,那么你正在做的事情是完全正确的。因此,如果您的方式导致简单性,那就是 React-Way。在我看来,情况就是如此。

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

编辑:

定义之词:"反应方式">

一旦您具有相同的输入,则每次代码变得可预测时都会产生相同的输出。由于代码可预测,因此您可以实现简单性。这些是 Pete Hunt 用来描述 React 意图的术语。因此,如果您保持可预测性并最终实现简单性,那么您就是在以反应方式进行。

在上述混合的情况下,这两个规则都适用,因此是我上面提供的定义中的"反应方式"。

我在这里的建议是不要使用mixin。清理组件的最佳方法是从组件中删除此逻辑,并且根本不根据检查身份验证的结果呈现组件。

这样做的问题是你有一个不再一致的组件,因为它依赖于它的道具以外的东西。除了将问题向上推之外,这并没有做太多事情,但它确实允许您拥有一个更纯粹的组件。

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

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