typescript - Pasar un Hook useState tipado a un componente hijo se lee como indefinido incluso cuando defaultState no es indefinido
Tengo el siguiente fragmento de código que es una parte de todo el conjunto. Básicamente, estoy intentando tener un formulario, con la opción de crear múltiples entradas del mismo formulario al hacer clic en un botón. El objetivo es almacenar los datos en un arreglo de objetos donde cada objeto representa un formulario.
Componente Padre
export interface IExperience {
position: string,
location: string,
startDate: string,
endDate: string,
description: string
}
const Experience = () => {
let [preview,setPreview] = useState(false)
let [data,setData] = useState<IExperience[]>([{position: '', location: '', startDate: '', endDate: '', description: ''}]) // Default state is not undefined
let [button,setButton] = useState('Edit')
return (
<div className={styles.visitorContainer}>
<Nav />
{preview ? <Message setPreview={setPreview} data={data} setData={setData} /> : <Preview setPreview={setPreview} data={data} setData={setData} button={button} setButton={setButton}/>}
<Foot />
</div>
)
}
export default Experience
Ignora la parte de la vista previa ya que es redundante para el problema que estoy enfrentando.
Componente Hijo
import React from 'react'
import { ReactNode, useState } from 'react'
import { IExperience } from '.'
import { Preview } from './preview'
export const Message = ( { setPreview }: any, { data,setData }: any ) => {
let [count,setCount] = useState(0)
let formRows: ReactNode = []
const formHandler = (i:number) => {
console.log(data) //Console log here also shows data is undefined
return formRows = [
(<div key={`innerDiv${i}`}>
<div><h2>Entry {i+1}</h2></div>
<div>
<label>Position</label>
<input type="text" placeholder='Engineer' onChange={(e) => setData({...data,position: e.target.value})} value={data.position} /> //Error is here (data is undefined)
</div>
</div>)
]
}
const updateHandler = () => {
setCount(prev => prev+1)
}
return (
<div>
<div>
<div>
</div>
<form onSubmit={(e) => sendData(e)}>
{[...Array(count+1)].map((d,i) => (<div key={`outerDiv${i}`} >{formHandler(i)}</div>))}
<div>
<input type="button" value='+' onClick={() => updateHandler()} />
</div>
</form>
</div>
</div>
)
}
De nuevo estoy omitiendo cosas redundantes para que se mantenga enfocado en el problema.
He estado investigando esto durante los últimos días y no pude encontrar una solución en línea, así que recurrí a publicar mi propia pregunta.
Espero que este código sea claro :)
Respuesta #1
Los componentes de React solo aceptan un único objeto props. El componente Message en tu fragmento de código está recibiendo dos argumentos.
export const Message = (
{ setPreview }: any, // arg 1
{ data, setData }: any // arg 2 undefined!
) => {
Deberías desestructurar todas las props del primer argumento, el objeto props. Por favor, verifica dos veces los tipos ya que no estoy muy familiarizado con Typescript.
interface I_Message {
setPreview: React.Dispatch<SetStateAction<boolean>>,
data: IExperience[],
setData: React.Dispatch<SetStateAction<IExperience>>
}
export const Message = ({ setPreview, data, setData }: I_Message) => {
...
