色々とコンポーネント化していくと(inputのtypeを変更できる汎用性を持った)テキスト入力だけのコンポーネントをも欲しくなった。
しかしそうなると親で値を管理したいはずなので面倒だなぁって思っていましたが意外と楽だった。
概要
親から子に値を渡してもReadしかできないので親のuseStateの値更新する関数をそのまま子コンポーネント に渡す。
子コンポーネント
...any
使っちゃいました。
import styles from './FormText.module.scss'
import { useState } from 'react'
export const FormText = ({
className,
type,
label,
onChange,
}: {
className?: string
label: string
type: string
onChange: (e) => void
}) => {
const [name, setName] = useState('')
const handleSetName = (e: React.ChangeEvent<HTMLInputElement> | any) => {
if (onChange) {
onChange(e.target.value)
}
setName(e.target.value)
}
return (
<>
<div className="form_text">
<label htmlFor="">{label}</label>
<input type={type} value={name} onChange={handleSetName} />
{name}
</div>
</>
)
}
親コンポーネント
親コンポーネントでは通常のinputを使っているのと変わらないような感じでonChangeのとこにuseStateの値をセットする関数をいれる。
これでtypeがtextとpassword別々で値を管理できる🎉
import { useState } from 'react'
import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import { getSortedPostsData } from '../lib/posts'
import { GetStaticProps } from 'next'
import { Section } from '../components/Section'
import { Sheet } from '../components/Sheet/Sheet'
import { FormText } from '../components/FormText/FormText'
export default function Home({
allPostsData,
}: {
allPostsData: {
title: string
}[]
}) {
const [name, setName] = useState('')
const [passWord, setPassWord] = useState('')
return (
<Layout home>
<main>
<Section>
<Sheet>
<FormText label="text" type="text" onChange={setName} />
<FormText label="text" type="password" onChange={setPassWord} />
</Sheet>
</Section>
</main>
</Layout>
)
}
export const getStaticProps: GetStaticProps = async () => {
const allPostsData = getSortedPostsData()
return {
props: {
allPostsData,
},
}
}
ひとこと
いつもevent系で型の解がわからないです...。
わかる人がいれば教えていただきたいです。