reactjs - 在react和typescript中解构useState中的状态

标签 reactjs typescript

有没有办法解构具有指定形状的当前状态?我在 personJob 中有一个当前状态,但我希望能够指定要查看的对象(当我单击一个按钮时,该按钮将切片该特定对象并仅呈现该数据)。

当我尝试按该索引进行切片时,我在 TypeScript const {company,dates,duty,title} = personJob[value]; 中收到错误

错误是:

Cannot destructure property 'company' of 'personJob[value]' as it is undefined.

组件:

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const url = 'https://course-api.com/react-tabs-project';

interface IPerson {
    id: string;
    company: string;
    dates: string;
    duties: string[];
    title: string;
}

function App() {
    const [personJob, setPersonJob] = useState<IPerson[]>([]);
    const [value, setValue] = useState<number>(0);

    const fetchData = async () => {
        const response = await axios(url);
        setPersonJob(response.data);
    };

    useEffect(() => {
        fetchData();
    }, []);

    const { company, dates, duties, title, id } = personJob[value];

    return (
        <main>
            <h1>Jobs</h1>
            {personJob.map((job, index) => {
                return (
                    <button key={job.id} onClick={() => setValue(index)}>
                        {job.company}
                    </button>
                );
            })}
            <section>
                <article className="border-2 px-5 py-5">
                    <div key={id}>
                        <h2>{title}</h2>
                        <h3>{company}</h3>
                        <p>{dates}</p>
                        {duties.map((duty) => {
                            return <div>*** {duty}</div>;
                        })}
                        <button type="button">More Info</button>
                    </div>
                </article>
            </section>
        </main>
    );
}

export default App;

最佳答案

问题

在初始渲染时,personJob 仍然是一个空数组,并且 personJob[0] 未定义,因此无法从中解构值。

解决方案

  1. 提供一个后备对象来解构,personJob[value] || {}
  2. 如果 personJob[value] 为真且存在,则有条件地渲染部分

代码:

function App() {
  const [personJob, setPersonJob] = useState<IPerson[]>([]);
  const [value, setValue] = useState<number>(0);

  const fetchData = async () => {
    const response = await axios(url);
    setPersonJob(response.data);
  };

  useEffect(() => {
    fetchData();
  }, []);

  const { company, dates, duties, title, id } = personJob[value] || {}; // <-- fallback for destructuring

  return (
    <main>
      <h1>Jobs</h1>
      {personJob.map((job, index) => {
        return (
          <button key={job.id} onClick={() => setValue(index)}>
            {job.company}
          </button>
        );
      })}
      {personJob[value] && <section> // <-- conditionally render section if data available
        <article className="border-2 px-5 py-5">
          <div key={id}>
            <h2>{title}</h2>
            <h3>{company}</h3>
            <p>{dates}</p>
            {duties.map((duty) => {
              return <div>*** {duty}</div>;
            })}
            <button type="button">More Info</button>
          </div>
        </article>
      </section>}
    </main>
  );
}

演示

Edit deconstructing-state-in-usestate-in-react-and-typescript

关于reactjs - 在react和typescript中解构useState中的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65317922/

相关文章:

reactjs - 无法在 Visual Studio C# ASP 内的 React 应用程序上使用 Material-UI。 NET核心网络应用程序

reactjs - React props 加载速度不够快

reactjs - (React-Native) undefined 不是一个对象(评估 _'this.props.navigation.navigate' )

javascript - 粘贴事件中的 typescript 回调为空

javascript - 去掉每个文件angular 6的文件扩展名

reactjs - 在 React v15 中渲染数组时是否需要项目键?

reactjs - React-router 键入 url 并在 tomcat 上刷新,elastic beanstalk

typescript - 递归数组类型 typescript

typescript - webpack-dev-server 和 ts-loader 不会在界面更改时重新加载

reactjs - 如何在样式组件中使用 font-weight 和 font-family ?