Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React global component

I am coming from a vue.js background and I have just recently started looking into react.

I have a component: PageContent.jsx and I wish to use it without constantly having to import it to be able to use it inside the render function (JSX).

In vue it is possible to globalise a component using:

Vue.component(componentName, componentObject)

Is there anything similar in react?

like image 798
Stan Hurks Avatar asked Jun 22 '18 20:06

Stan Hurks


People also ask

What is a global state in React?

Role of the global state. In React, originally, the state is held and modified within the same React component . In most applications, different components may need to access and update the same state. This is achieved by introducing the global states in your app.

Are there global variables in React?

You Can Definitely Use Global Variables To Manage Global State In React.

What is global context in React?

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language. For example, in the code below we manually thread through a “theme” prop in order to style the Button component: class App extends React.


2 Answers

Hmm, there isn't any kind of "global" component in React. Each component has to be imported or passed as a prop. You have a few options if you want to avoid adding an import to each file though:

1) Create a Higher Order Component that renders the PageContent and the wrapped component.

import PageContent from './PageContent';

const withPageContent = WrappedComponent => {
  return class extends React.Component {
    render () {
      return (
        <PageContent>
          <WrappedComponent />
        </PageContent>
      )
    }
  }
};

export default withPageContent;

// Usage

import withPageContent from './withPageContent';

class MyComponent extends React.Component {
  render () {
    return (
      <div>
        I'm wrapped in PageContent!
      </div>
    )
  }
}

export default withPageContent(MyComponent);

2) Pass PageContent as a prop to a component:

import PageContent from './PageContent';

export default class App extends React.Component {
  render() {
    return (
      <React.Fragment>
        <Child1 content={PageContent} />
        <Child2 content={PageContent} />
      </React.Fragment>
    )
  }
}

// Usage

export default class Child1 extends React.Component {
  render () {
    const PageContent = this.props.content;
    return (
      <PageContent>
        I'm wrapped in PageContent!
      </PageContent>
    )
  }
}

export default class Child2 extends React.Component {
  render () {
    const PageContent = this.props.content;
    return (
      <PageContent>
        I'm wrapped in PageContent!
      </PageContent>
    )
  }
}
like image 90
Chase DeAnda Avatar answered Nov 15 '22 06:11

Chase DeAnda


I very much agree with Chase's answer. Still if you need another approach you can use the context api. You can declare in the App root, or another nested components tree, a collection of components that you want to easily access.

Here is an example with the useContext hook, but hooks is not a must. The structure is the standard create-react-app structure.

The component we would like to access globally - src/deep/Header.js:

function Header() {
  return (
    <h1>
      I am a global component
    </h1>
  );
}

export default Header;

The context creation - src/global-components-context.js:

import React from 'react';

const MyContext = React.createContext(null);

export default MyContext;

The grouping of the global-components - src/global-components.js:

import Header from './deep/Header';

const contextValue = {
  Header,
};

export default contextValue;

The app init file - src/index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import MyContext from './global-components-context';
import contextValue from './global-component';

ReactDOM.render(
  <MyContext.Provider value={contextValue}>
    <App />
  </MyContext.Provider>,
  document.getElementById('root')
);

Using the component without importing it - src/App.js:

import { useContext } from 'react';
import globalComponent from './global-components-context';

function App() {
  const Context = useContext(globalComponent);
  return (
    <div className="App">
      <Context.Header />
    </div>
  );
}

export default App;

I think this is the most global components you can have in react. Note that you still need to import the context wherever you would like to use a global component.

Also one more disclaimer, global components are very hard to test and often to reason about. I believe that is why there is no standard solution for it in react.

Hope I could help

like image 28
U Rogel Avatar answered Nov 15 '22 05:11

U Rogel