Is there a way to define a function to hook before each component in my app is mounted?
The idea is that if a component is blacklisted it doesn't mount at all.
The solution must leave the components unmodified for backward compatibility and should run in production (so rewire and other testing tools are probably off the table but open to suggestions :) )
Example
//something like this... ReactDOM.beforeEachComponentMount( (component, action) => { if(isBlacklisted(component)){ action.cancelMountComponent(); } }
6 Answers
Answers 1
Could you write a simple Babel plugin that transforms blacklisted components to a noop functional component () => {}
at compile time?
Answers 2
You could wrap the required components inside a higher order component that checks whether the component is blacklisted or not.
for example :
class YourComponent extends Component { constructor(props){ super(props); } render(){ return( // your component goes here .. ); } } export default WithPermission(YourComponent);
check if the component needs to be rendered or not inside the HOC WithPermission.
function withPermission(YourComponent) { class WithPermission extends React.Component { constructor(props) { super(props); } // you can check the props inside ComponentDidMount and set a flag if // the component satisfies the criteria for rendering. render() { const {blacklistedComponents,...rest} = this.props; if(!blackListedComponents){ return <YourComponent {...rest} /> } else{ return null; } } } }
Answers 3
The best idea I can think of is to "shim" react
and Component
if you are using webpack you can use this: https://webpack.js.org/guides/shimming/
in the bottom line that means instead of importing react
you will import your own class of react.
In your new class you could extend React Component and place a check on the render
function or something similar.
Answers 4
There is no such functionality out of box.
You may shim React rendering cycle, I mean shim React.createElement
method and validate component before it is added to VDOM
All JSX is processed through React.createElement
e.g. at the start of app add
let React = require('react'); let originalCreateElement = React.createElement; React.createElement = function() { let componentConstructorOrStringTagName = arguments[0]; if (isBlacklisted(componentConstructorOrStringTagName)) { return; } return originalCreateElement.apply(this, arguments); }
Answers 5
You could implement a custom ESLint rule and catch this as soon as a dev tries to use a blacklisted components. The id-blacklist rule is similar to what you want, but at the identifier level. The source code looks simple. Maybe you can adapt it to disallow more then just identifiers.
Answers 6
Consider the following solution:
Let there be a file where you declare which components are blacklisted:
let blacklist = [{ name: 'secretComponent', invoke: (props)=> { return <SecretComponent ...props /> }, isBlacklisted: true },{ name: 'home', invoke: (props)=> { return <HomeComponent ...props /> }, isBlacklisted: false },{ name: 'login', invoke: (props)=> { return <LoginComponent ...props /> }, isBlacklisted: false }];
Define a Higher Order Component like below:
function renderIfNotBlacklisted(name) { let component = blacklist.map(x=> x.name == name); //blacklist from above if (!component.isBlacklisted){ return component.invoke(); } //else can be handled as you will //You can keep a default component to render or send empty values }
Call this component in the render function wherever you want this feature to work. This way you have a centralized location to managed blacklisted components (blacklist.json can be in the root of react project or fetched from API on first run)
0 comments:
Post a Comment