Reactjs,打字稿

Reactjs, typescript

我正在尝试创建 Searchbar,我可以在其中获取作者并显示作者 ID 和图片,为什么我会收到此错误(任何 属性 'toLowerCase' 在类型 [ 上不存在=14=]) 在我的代码中?

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

function Searchbar() {
  const [query, setQuery] = useState('');
  const [data, setData] = useState([]);

  // Add one more state to store the authors being searched for

  const [searchResults, setSearchResults] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const res = await axios.get(`https://picsum.photos/v2/list`);
      setData(res.data);
    };
    fetchData();
  }, []);

  useEffect(() => {
    setSearchResults(
      data.filter((authorData) =>
        authorData['author'].toLowerCase().includes(query)
      )
    );
  }, [query, data]);

  return (
    <div className='app'>
      <input
        className='search'
        placeholder='Search...'
        onChange={(e) => setQuery(e.target.value.toLowerCase())}
      />
      <div>
        {searchResults.map((author) => (
          <div>{author}</div>
        ))}
      </div>
    </div>
  );
}

export default Searchbar;

问题似乎是您依赖打字稿来推断 api 调用的类型。 (相反,打字稿将其推断为 never 如果您尝试使用它,它总是会出错)

要解决此问题,只需设置获取数据的类型

type fetchData = {
  id: number,
  author: string,
  width: number,
  height: number,
  url: string,
  download_url: string
}

然后这样设置你的状态

const [data, setData] = useState<fetchData[]>([]);
const [searchResults, setSearchResults] = useState<fetchData[]>([]);

完整代码

import { useEffect, useState } from "react";
import axios from "axios";

type fetchData = {
  id: number,
  author: string,
  width: number,
  height: number,
  url: string,
  download_url: string
}

function Searchbar() {
  const [query, setQuery] = useState("");

  const [data, setData] = useState<fetchData[]>([]);

  // Add one more state to store the authors being searched for

  const [searchResults, setSearchResults] = useState<fetchData[]>([]);

  useEffect(() => {
    const fetchData = async () => {
      const res = await axios.get(`https://picsum.photos/v2/list`);
      setData(res.data);
    };
    fetchData();
  }, []);

  useEffect(() => {
    setSearchResults(
      data.filter((authorData : fetchData) =>
        authorData.author.toLowerCase().includes(query)
      )
    );
  }, [query, data]);

  return (
    <div className="app">
      <input
        className="search"
        placeholder="Search..."
        onChange={(e) => setQuery(e.target.value.toLowerCase())}
      />
      <div>
        {searchResults.map((author) => (
          <div key={author.id}>{author.author}</div>
        ))}
      </div>
    </div>
  );
}

export default Searchbar;