LoginSignup
78
84

More than 1 year has passed since last update.

【React / Next】親Componentから共通Componentをchildrenで渡して、子Component側で引数を追加したい

Last updated at Posted at 2022-06-19

親から渡ってきた children に props を追加したかったので、その個人的な備忘録です。

やりたいこと

  • 親Componentから 共通Component を children として 子Componentへ渡す
  • 子Component側で持つべきメソッドを、子に渡ってきた時に追加したい

環境

  • React: 17.0.2
  • Next: 11.1.3
  • @chakra-ui/react: ^1.8.5

サンプルコード

親Component

import { CommonForm } from 'components/commonForm';

interface Props {
  email: string;
}

export const ParentComponent = ({ email }: Props) => {
  return (
    // 省略
	{/* Container へ渡す children は 共通Component */}
    <HogeContainer email={email}>
	  {/* この時のpropsは1つだけ */}
      <CommonForm email={email} />
    </HogeContainer>
  );
};

子Component

import { Container } from '@chakra-ui/react';
import { cloneElement, ReactElement } from 'react';

interface Props {
  email: string;
  children: ReactNode;
}

export const Container = ({ email, children }: Props) => {
  // 省略

  const changeTitle = () => {
    // 処理
  }

  // children(共通Component) へ追加したい props を定義
  const additionalProps = { onCompleted: changeTitle };

  // cloneElement で children へ props を追加する
  const clonedForm = cloneElement(children as ReactElement, {
    ...additionalProps,
  });

  return (
    <Container>
      {/* props が追加された children(共通Component) */}
      <>{clonedForm}</>
    </Container>
  );
};

共通Component(children)

import { Box } from '@chakra-ui/react';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { FormInputData } from './types';

interface Props {
  email: string;
  onCompleted?: () => void;
}

export const CommonForm = ({ email, onCompleted}: Props) => {
  const [isLoading, setIsLoading] = useState(false);
  const [message, setMessage] = useState('');
  const { registrationHandler } = useRegistration(role, token);

  const onSubmit = async (data: FormInputData) => {
    setIsLoading(true);
    const response = await someHandler(data).finally(() => {
      setIsLoading(false);
    });
    // 省略
    onCompleted!();
  };

  const {
    handleSubmit,
    control,
    formState: { errors },
  } = useForm<FormInputData>({
    // 省略
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)} noValidate>
      // 省略
      <Box>
        <Button type={'submit'} isLoading={isLoading}>
          登録
        </Button>
      </Box>
    </form>
  );
};

参考文献

78
84
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
78
84