Reputation: 1322
I'm trying to develop a React mixin to check the user access level before rendering the component.
If the user doesn't have the permission to see the component, I would like to disable the rendering of the component. I've been looking for something build in react to handle this but found nothing, so I did that:
var AuthentLevelMixin = {
componentWillMount: function() {
if(!Auth.check()) {
// Disable component render method
this.render = function () {
return false;
}
}
}
}
It works as expected but I feel like it's the "dirty way".
So my question is: what is the "React way" for doing the same as this snippet ?
Upvotes: 4
Views: 7995
Reputation: 1049
My advice here would be to not use a mixin. The best way to clean up your component is to remove this logic from the component, and simply not render the component based on the result of checking Auth.
The problem with this is that you have a component that is no longer consistent, because it depends on something other than its props. This doesn't really do much other than push the problem upwards, but it does allow you to have one more pure component.
I can see why the mixin is attractive though, so here's a simpler way of doing what you need that doesn't involve dynamically swapping the render method:
var PreventRenderUnlessAuthMixin = {
componentWillMount: function () {
var oldRender = this.render;
this.render = function () {
return Auth.check() ? this.render() : <div />
}.bind(this);
}
}
Upvotes: 0
Reputation: 86260
For a mixin this is about the best you can do. It's just a simple early return in render.
var AuthentLevelMixin {
isAuthenticated: function(){
return Auth.check();
}
};
var C = React.createClass({
mixins: [AuthentLevelMixin],
render: function(){
if (!this.isAuthenticated()) return <div />;
return (
<div>...</div>
);
}
});
If you decide to go with your initial strategy (I don't recommend it), it just needs to be modified slightly:
// 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;
}
}
Upvotes: 5
Reputation: 1009
If you want to handle the authorization inside your mixin without adding logic to your component you are doing it the right way. BUT: Every component implementing this mixin should then be aware of what happens within this mixin. If the result you expect is, that nothing is rendered, then you are perfectly right with what you are doing. So if your way is resulting in simplicity it is the React-Way. And in my Opinion this is the case.
In the componentWillMount lifecycle event you will capture the moment right before rendering - which is a great time to prevent rendering. So I really dont see anything speaking against your code.
EDIT:
aproach of defining: "react way"
Once you have the same input resulting in the same output every time your code becomes predictable. With your code being predictable you achieve simplicity. These are terms used by Pete Hunt to describe the intentions of React. So therefor if you stay predictable and in result achieving simplicity you are doing it the react way.
In case of the above mixin both these rules apply and is therefor the "react way" in the definition I have provided above.
Upvotes: 3