I am trying to pass data from Parent to Child (dialog) component but it considering it as null . The data is coming from api and rendering in the parent component based on id, same data is to be displayed on the form in the dialog when edit button is clicked. It is showing error in Parent Type 'null' is not assignable to type '{ id: number; name: string; email: string; } | undefined'.ts(2322) dialogBox.tsx(13, 3): The expected type comes from property 'postData' which is declared here on type 'IntrinsicAttributes & DialogProps' and in Dialog this error 'postData' is possibly 'undefined'.ts(18048) Parents
interface Post {
id: number;
name: string ;
email: string;
}
export default function ProfileBox2 () {
const [open, setOpen] = React.useState(false);
const [posts, setPosts] = useState<Post | null>(null);
const [error, setError] = useState<string | null>(null);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
if (!response.ok) {
throw new Error('Failed to fetch post');
}
const data: Post = await response.json();
setPosts(data);
} catch (error) {
if (typeof error === 'string') {
setError(error);
} else {
setError('An error occurred while fetching data');
}
}
};
fetchData();
}, []);
return (
<React.Fragment>
<div>
<h1>Profile</h1>
{error && <div>Error: {error}</div>}
{posts && (
<div>
<p>Name: {posts.name}</p>
<Divider/>
<p>Email: {posts.email}</p>
</div>
)}
<Button onClick={handleClickOpen}>Edit</Button>
<DialogBox isOpen={open} postData={posts}/>
</div>
</React.Fragment>
);
};
Dialog (child)
interface DialogProps {
isOpen: boolean;
onClose?: () => void;
postData? : {
id: number;
name: string;
email: string;
};
}
const DialogBox: React.FC<DialogProps> = ({postData , isOpen, onClose}) => {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<React.Fragment>
<Dialog
open={isOpen}
onClose={handleClose}
PaperProps={{
component: 'form',
onSubmit: (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const formJson = Object.fromEntries((formData as any).entries());
const email = formJson.email;
console.log(email);
handleClose();
},
}}
>
<DialogTitle>Dialog </DialogTitle>
<DialogContent>
<DialogContentText>
Edit Email address
</DialogContentText>
{/* {PostData && PostData.email && */}
<TextField
autoFocus
required
margin="dense"
id="name"
name="email"
label="Email Address"
type="email"
fullWidth
variant="standard"
value = {postData.email}
/>
{/* } */}
</DialogContent>
<DialogActions>
<Button type="submit">Edit</Button>
<Button onClick={handleClose}>Cancel</Button>
</DialogActions>
</Dialog>
</React.Fragment>
);
}
export default DialogBox;
Things to note:
The type below expects either no prop (similar to undefined
) or the right object:
postData? : {
id: number;
name: string;
email: string;
}
But, since the initial value of posts
is null
, you are violating that. So TypeScript complains.
Given your types, where postData
can be undefined. The following will break : value = {postData.email}
. And that is what typescript is complaining you about.
Update your type to allow null
.
postData : {
id: number;
name: string;
email: string;
} | null
value = {postData?.email ?? ''}