简体   繁体   English

在 React 功能组件 state 和 Typescript 中嵌套了 object

[英]Nested object in React functional component state with Typescript

I have an nested object in React functional component state, but I only can access first level of object if I use any type.我在 React 功能组件 state 中有一个嵌套的 object,但如果我使用any类型,我只能访问 object 的第一级。

export default function Detail() {
    const [user, setUser] = useState<any>({});
    const { id } = useParams();


    useEffect(() => {
        fetch('http://localhost:4000/users/' + id)
        .then(response => {
            return response.json();
        })
        .then(data => {
            setUser(data);
        })
    }, []);
    
    

    return (
        <div>
            <h1>Detail view</h1>
            <p>ID: { user.id }</p>
            <p>First name: { user.first_name }</p>
            <p>Last name: { user.last_name }</p>
            <p>Email: { user.email }</p>
            <p>Gender: { user.gender }</p>
        </div>
    );
}

When trying to access user.company.name it throws尝试访问user.company.name时抛出

Detail.tsx:40 Uncaught TypeError: Cannot read properties of undefined (reading 'name')

I made an interface for it, but it gives me an error if I'm trying to use it for state type.我为它制作了一个接口,但如果我试图将它用于 state 类型,它会给我一个错误。

interface UserInfo {
    id: number;
    first_name: string;
    last_name: string;
    email: string;
    gender: string;
    company: {
        name: string;
        department: string;
    }
}
Argument of type '{}' is not assignable to parameter of type 'UserInfo | (() => UserInfo)'.

How can I use defined interface as state type?如何使用定义的接口作为 state 类型?

Don't use the any type.不要使用any类型。 TypeScript can't help you if you don't use actual types.如果你不使用实际类型,TypeScript 帮不了你。 Type the state narrowly.严格键入 state。

Don't use an empty object as your default value.不要使用空的 object 作为默认值。 It isn't useful.这没有用。 Use a value that clearly indicates that the data isn't available yet.使用明确指示数据尚不可用的值。


type PossibleUserInfo = UserInfo | null;

const [user, setUser] = useState<PossibleUserInfo>(null);

Then, handle the case where you don't have the data yet explicitly.然后,处理您还没有明确数据的情况。

It isn't useful to spit out a div with a bunch of paragraphs containing a label but not data.用一堆包含 label 但不包含数据的段落吐出一个 div 是没有用的。


if (user) {
    return (
        <div>
            <h1>Detail view</h1>
            <p>ID: { user.id }</p>
            <p>First name: { user.first_name }</p>
            <p>Last name: { user.last_name }</p>
            <p>Email: { user.email }</p>
            <p>Gender: { user.gender }</p>
        </div>
    );
}

return (
    <div>
        <h1>Default view</h1>
        <Loading />
    </div>
);

… where Loading is a component that shows (for example) a loading spinner . …其中Loading是一个显示(例如) 加载微调器的组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM