loading...

Injecting components into re-usable modules with React context?

carlbarrdahl profile image Carl Barrdahl ・2 min read

Here's an idea I've been pondering for awhile:

What if we passed components through React's context API instead of importing them at the top of each component?

Component libraries are great, however, we still have to piece together the components into modules. This way we could "inject" components making the modules easier to style.

I imagine it looking something like this:

// Shared module for authentication flows
import { useComponents } from "react-use-components"

export const LoginModule = ({ onLogin }) => {
  // Get the components from `React.useContext`
  const { Button, Form, Input, Label } = useComponents()

  const [state, setState] = useState({ email: "" })
  const [error, setError] = useState(null)

  async function handleSubmit(e) {
    /* call api, handle token, errors etc */
  }
  return (
    <Form onSubmit={handleSubmit}>
      <Label htmlFor="email">
        <Input id="email" value={state.email} />
      </Label>
      <Button type="submit">Login</Button>
    </Form>
  )
}

And then set the components to the context in your app:

// App.js
import ComponentProvider from "react-use-components"
import { LoginModule, SignupModule } from "standard-auth-module"

import * as Components from "my-awesome-components"

export default ({ navigate }) => (
  <ComponentProvider components={Components}>
    <LoginModule request={api.login} onLogin={user => navigate("/dashboard")} />
  </ComponentProvider>
)

Here's how the library would look like:


import React, { createContext, useContext } from "react"

const ComponentContext = createContext()

export const useComponents = () => useContext(ComponentContext)

export const ComponentProvider = ({ components: value, ...props }) =>
  React.createElement(ComponentContext.Provider, { value, ...props })

export default ComponentProvider

The point of this would be to build re-usable modules much like an higher abstraction over component libraries. Component libraries would be used for styling and modules for behaviour.

This comes with some obvious challenges like:

  • How do we control layout?
  • How do we make sure components in the context have the required prop-types? Limit to single element pattern?
  • What about performance?
  • Translations?

What are your thoughts? What kind of re-usable components could be built?

Resources

Demo (https://github.com/carlbarrdahl/react-use-components)
Single Element Pattern (https://github.com/diegohaz/singel)

Posted on Oct 19 '19 by:

carlbarrdahl profile

Carl Barrdahl

@carlbarrdahl

coding / music / skiing / hiking / traveling

Discussion

markdown guide