Skip to content

doasync/use-component

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

useComponent React hook

NPM Version NPM Downloads GitHub issues Telegram

Get the resulting component you want to wrap inside your target component by checking props, context or a fallback.

Installation

npm install use-component

or

yarn add use-component

Example

https://codesandbox.io/s/vm2zlr1qo3

Usage

useComponent

import { useComponent } from 'use-component'

Pass an entry of current component to the hook (this means that you need wrap your current component in an object and pass it to the entry option) as well as component from prop, a fallback, or an object of components and you will get a resulting component:

export const Input = ({
  children,
  component,
  ...fieldProps
}) => {
  const Component = useComponent({
    entry: { Input },
    component,
    fallback: 'input',
  });

  return (
    <Field {...fieldProps}>
      {({ input, meta, ...customProps }) => {
        return (
          <>
            {typeof Component === 'string' ? (
              <Component {...input} {...customProps} />
            ) : (
              <Component
                {...input}
                {...customProps}
                label={children}
                meta={meta}
                message={getErrorMessage(meta)}
              />
            )}
          </>
        );
      }}
    </Field>
  );
};

You can now pass any component as prop which will be used inside Input component. You can pass a styled component, for example, or any custom component, which will receive internal input, meta, label and message props.

<Input
  component={CustomInput}
  type="password"
  name="password"
  placeholder="Password"
/>

ComponentsContext

You can also create a context provider:

export const Form = ({
  children,
  onSubmit,
  component,
  components,
  ...otherProps
}) => {
  const Component = useComponent({
    entry: { Form },
    component,
    fallback: 'form',
    components,
  });

  const { handleSubmit } = useContext(FormContext);

  return (
    <ComponentsContext.Provider value={components}>
      <Component onSubmit={onSubmit || handleSubmit} {...otherProps}>
        {children}
      </Component>
    </ComponentsContext.Provider>
  );
};

And then just pass your components to it:

  <Form
    component={FormBox}
    components={{
      Input: StyledInput,
      ErrorMessage: ErrorBox,
    }}
  >
    <Heading>Login</Heading>
    <LoginFormBox>
      <FieldBox>
        <FieldLabelText>Email</FieldLabelText>
        <Input
          type="text"
          name="login"
          placeholder="E-mail"
        />
      </FieldBox>
      <FieldBox>
        <FieldLabelText>Password</FieldLabelText>
        <Input
          component={CustomInput}
          type="password"
          name="password"
          placeholder="Password"
        />
      </FieldBox>
      <StyledButton type="submit">Login</StyledButton>
    </LoginFormBox>
  </Form>

You can still use your original Input and ErrorMessage, but they will use your specified components under the hood passing some internal props to them.

Tip

If you found this hook useful, please star this package on GitHub

Author

@doasync

About

useComponent React hook

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published