0

I have a large React app and I have a few components that I would like to completely disable from a config or global level. Is there any kind of global hook that I can use that is called before any component is rendered? If so, I imagine I can check the name of the component and return null if the name is on the disabled list. How would you do this?

Byron Sommardahl
  • 12,103
  • 14
  • 68
  • 126
  • If you have a global state store like redux, you can store a flag in the state, then just disable the component based on that property in the component class. – mhatch Sep 28 '18 at 19:02
  • ... redux or context (or even window.varFlag) ... and you don't have to return `
    ` - rendering null to virtual DOM removes entirely component from real DOM
    – xadm Sep 28 '18 at 19:07
  • Can you use the state? i.e. `` and then just enabled/disable by updating its state in its calling parent record, like `compref.setState({'enabled':true/false})`? Worried about missing your intent here. – HoldOffHunger Sep 28 '18 at 19:09
  • @Byron edit question text/title - add 'feature flag'? – xadm Sep 28 '18 at 19:14
  • @HoldOffHunger it wouldn't be 'global config driven' and not 'completely disable' - not hide it by css, don't render it rather. It's enough to not render children. Using refs would be an overkill for that (+ modifying 'body' of hidden component), managing them globally? Parent != global. Global & connected parent ? then passing prop would be enough (probably one time change - not dynamic), no need for refs.... ect. – xadm Sep 28 '18 at 19:40

3 Answers3

0

There are a lot of ways to do this:

React's Context API allows you pass props through every level of the component tree so you can use them as flags to enable/disable components. Should be used sparingly however.

Higher Order Components are basically just functions that return a component. You could wrap your components in logic to render them as needed.

Or of course you could use a global state manager like redux to set global states.

Andy Mai
  • 76
  • 5
0

There are many ways to do this, so, I'll just describe one simple way: using references and updating the states accordingly.

Full working feature hide/showing sandbox online: codesandbox.io ReactJS Feature Hide/Show Demo

Defined are two classes, class Feature extends React.Component and class App extends React.Component. The render() for <Feature/> is...

  render() {
    if (!this.state.enabled) {
      return <div />;
    }
    return (
      <div className="Feature">
        <h1>My Feature!</h1>
      </div>
    );
  }

And the option for enabling/disabling a feature in <App /> would handle display/hiding like so...

  handleOnClick(e) {
    if (e.target.checked) {
      this.feature.setState({ enabled: true });
    } else {
      this.feature.setState({ enabled: false });
    }
  }

Of course, you need to make sure that <Feature /> has the reference set...

    <Feature
      ref={instance => {
        this.feature = instance;
      }}
    />
HoldOffHunger
  • 10,963
  • 6
  • 53
  • 100
  • and make it global for component placed deeper in structure .... ? it's definitively not a question about hidding direct child – xadm Sep 28 '18 at 19:58
  • This solution could work, but as I mentioned, I have a very large code base. I need a solution that is more at the framework-level. – Byron Sommardahl Sep 28 '18 at 21:56
0
  1. If you need simplest solution just use browser global vars and check it in render.

    render() { if( window.globalFlag ) return null return ( <div> feature content...

    Drawbacks:

    • modifying component,
    • using global scope,
    • some unnecessary code can be run earlier (f.e. constructor) and later (f.e. componentDidMount).
  2. Use HOCs - wrap your component - connecting with global store using redux or context API.

    <FlagsProvider store={flagStore}> <SomeComponent_1> <SomeComponent_2> <FlagsConsumer flag="someFeatureFlag"> <SomeFeatureComponent />

    <FlagsConsumer/> connects to store (redux connect would be an inner wrapper - composing HOCs) and conditionally renders <SomeFeatureComponent /> (or null).

    Of course HOC can pass received props to wrapped component - it can be functionally transparent.

  3. Don't reinvent the wheel - use some ready module, read tutorials, google for sth suitable.

HOC can also play a role of A/B testing.

xadm
  • 6,900
  • 3
  • 8
  • 17
  • I have a large code base. Going to each component and adding a HOC or a flag inside the component will be a LOT of work. Is there not some framework-level hook before any component is rendered? – Byron Sommardahl Sep 28 '18 at 21:55
  • It would hurt performance. Do you really need it for each component? Extend `React.Component` and use it as own base class (search & replace)? It would be removable feature for 'final deployment'. – xadm Sep 29 '18 at 07:52