You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从自定义Hook向组件传递数据?类型不匹配问题排查

解决TypeScript类型不匹配错误及代码优化

问题根源

  • useTable返回的data类型是Data | undefined(Data是键为分类名、值为DataTable[]的对象),但setData1需要的是DataTable[] | undefined,直接赋值导致类型不兼容。
  • Settings组件中解构useTable返回值时,多取了不存在的checkall和changeDatabase,不符合useTable的返回结构。
  • useTable内部更新data时未使用函数式更新,存在闭包导致的旧值引用问题。
  • filter回调的参数类型错误,误将单个数据项写成数组类型。

修复步骤

  1. 修正useTable的返回类型与数据更新逻辑

    • 给useTable明确返回类型,避免TS自动推断出错。
    • 使用函数式更新setData,确保获取最新的data状态。
    • 修正filter的参数类型,response是DataTable[],回调的第一个参数是单个DataTable项。
  2. 调整Settings组件的解构与赋值逻辑

    • 只解构useTable返回的两个值:data和columns。
    • 从data中取出对应分类的DataTable[](比如传入的"new"分类),再赋值给data1。
    • 给useEffect添加正确的依赖项,确保数据更新时能触发赋值。
  3. 优化useTable的参数使用

    • 可利用传入的actualcategory参数,让Hook直接返回对应分类的数据,简化组件逻辑。

修正后的完整代码

interface DataTable {
  [id: string | number]: string | number;
}

interface Data {
  [category: string]: DataTable[];
}

interface Column {
  col: {
    title: string;
    disp: boolean;
  };
}

const urls: string[] = [
  "https://jsonplaceholder.typicode.com/posts",
  "https://jsonplaceholder.typicode.com/comments",
  "https://jsonplaceholder.typicode.com/albums",
  "https://jsonplaceholder.typicode.com/photos",
  "https://jsonplaceholder.typicode.com/todos",
];

// 明确Hook的返回类型
const useTable = (idurl: number, actualcategory: string): [Data | undefined, Column[] | undefined] => {
  const [data, setData] = useState<Data>();
  const [columns, setColumns] = useState<Column[]>();

  const loadDatabase = () => {
    fetch(urls[idurl])
      .then((response) => response.json())
      .then((response: DataTable[]) => {
        // 使用函数式更新获取最新状态
        setData(prevData => ({
          ...prevData,
          new: response.filter((t: DataTable, i: number) => i > 50 && i < 100),
          removed: response.filter((t: DataTable, i: number) => i > 100 && i < 150),
          postponed: response.filter((t: DataTable, i: number) => i > 50 && i < 100),
        }));

        if (response.length > 0) {
          const objcolumn: Column[] = Object.keys(response[0]).map(t => ({
            col: { title: t, disp: true }
          }));
          setColumns(objcolumn);
        }
      });
  };

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

  return [data, columns];
};

export { useTable };

const Settings = () => { 
  // 只解构存在的返回值
  const [data, columns] = useTable(1, "new");  
  const [data1, setData1] = useState<DataTable[]>();

  useEffect(() => {
    // 取出对应分类的DataTable数组
    if (data) {
      setData1(data["new"]);
    }
  }, [data]); // 依赖data,确保数据更新时触发
 
  return <>></>;
};

额外优化建议

如果希望useTable直接返回指定分类的数据,可以修改Hook逻辑,进一步简化组件:

const useTable = (idurl: number, actualcategory: string): [DataTable[] | undefined, Column[] | undefined] => {
  const [categoryData, setCategoryData] = useState<DataTable[]>();
  const [columns, setColumns] = useState<Column[]>();

  const loadDatabase = () => {
    fetch(urls[idurl])
      .then((response) => response.json())
      .then((response: DataTable[]) => {
        // 根据分类筛选对应数据
        let targetData: DataTable[] = [];
        switch(actualcategory) {
          case "new":
            targetData = response.filter((t, i) => i > 50 && i < 100);
            break;
          case "removed":
            targetData = response.filter((t, i) => i > 100 && i < 150);
            break;
          case "postponed":
            targetData = response.filter((t, i) => i > 50 && i < 100);
            break;
          default:
            targetData = [];
        }
        setCategoryData(targetData);

        if (response.length > 0) {
          const objcolumn = Object.keys(response[0]).map(t => ({
            col: { title: t, disp: true }
          }));
          setColumns(objcolumn);
        }
      });
  };

  useEffect(() => {
    loadDatabase();
  }, [actualcategory]); // 依赖分类参数,分类变化时重新加载

  return [categoryData, columns];
};

// Settings组件中直接使用
const Settings = () => { 
  const [data1, columns] = useTable(1, "new");  

  return <>></>;
};

内容的提问来源于stack exchange,提问作者artur nowakowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:25:18