Reputation: 433
I'm getting an Object is possibly 'undefined'.
error on every property check and access after story &&
on the code below. It doesn't make sense to me, since the first check is checking whether story
exists, or not. If it didn't exist, wouldn't the ternary just short circuit, and return null
? I'm new to typescript (and newish to react). I'd be happy to hear any suggestions! Thanks!
import React, { useState, useEffect } from "react";
import { getStory } from "../services/hnAPI";
interface Props {
storyId: number;
}
export const Story: React.FC<Props> = (props) => {
const [story, setStory] = useState();
useEffect(() => {
getStory(props.storyId).then((data) => data && data.url && setStory(data));
}, [props.storyId]);
return story && story.url ? (
<a href={story.url}>{story.title}</a>
) : null;
};
Upvotes: 4
Views: 6653
Reputation: 6837
You should be passing a type argument to useState()
so it does not infer the state value as undefined
.
Here is an example
import React, { useState, useEffect } from 'react';
import { getStory } from '../services/hnAPI';
interface Props {
storyId: number;
}
interface Story {
id: number;
title: string;
url: string;
// properties for the Story
}
export const Story: React.FC<Props> = (props) => {
const [story, setStory] = useState<Story | null>(null);
useEffect(() => {
getStory(props.storyId).then((data: Story) => data && setStory(data));
}, [props.storyId]);
return story && story.url ? <a href={story.url}>{story.title}</a> : null;
};
P.S. Please never let a promise get uncatched. If you are making a API call is you getStory
function consider adding a catch
block and properly handle the error. Example in the same scenario.
export const Story: React.FC<Props> = (props) => {
const [story, setStory] = useState<Story | null>(null);
useEffect(() => {
getStory(props.storyId).then((data: Story) => data && setStory(data))
.catch(error => {
// handle the error
// you can use another state variable to store the error
});
}, [props.storyId]);
return story && story.url ? <a href={story.url}>{story.title}</a> : null;
};
Upvotes: 7