【问题标题】:react typescript : usestate type反应打字稿:usestate类型
【发布时间】:2020-08-22 17:31:45
【问题描述】:

我正在尝试从 firebase 获取我的项目并将其放入带有钩子的数组中。

一个项目看起来像:{name: "movie app", date: t, description: "this is my first app, a complete movie app"}

//hooks
const [projects, setProject] = useState([]);

//function for get projects
async function getprojects(){
    let finalProjects = [];
    await db.collection('projects').get().then((querySnapshot) => {
        querySnapshot.docs.map(res => {
             const a = res.data();
             finalProjects.push(a)
        })
        //error here
        setProjects(finalProjects)
    })
}

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

但是finalProjects.push(res.data()) 不起作用,因为“'DocumentData' 类型的参数不能分配给'never' 类型的参数。”但是我应该如何将我的所有项目放入projectssetProjects

【问题讨论】:

    标签: javascript reactjs typescript react-hooks


    【解决方案1】:

    Typescript 不知道您在状态中存储了什么,因此它不会让您将数据放入其中。您可以将其设为 any 数组(不太理想)或 DocumentData 数组。

    const [projects, setProject] = useState<any[]>([]);
    
    const [projects, setProject] = useState<DocumentData[]>([]);
    

    确保DocumentData 在范围内,从firestore 导入。

    【讨论】:

    • 我没有找到如何使用 DocumentData 但第一个解决方案有效! ty
    【解决方案2】:

    或者你可以做这样的事情。这样,您将输入您的状态,您还将获得doc.data()typed(我认为,在这方面做得更好的人可能会验证这一点)

    import {
      collection,
      getFirestore,
      getDocs,
      query,
      orderBy,
      DocumentData,
    } from "firebase/firestore";
    
    export interface ArticleProps {
      authorId: string;
      authorName: string;
      category: CategoryProps[];
      content: [];
      created: number;
      eventDate: number;
      heroImage: string;
      htmlData: string;
      preview: string;
      published: boolean;
      title: string;
      type: string;
      users: UserIdProps[];
    }
    
    
    const [allArticles, setAllArticles] = useState<ArticleProps[]>([]);
      const fetchEvents = async () => {
        const eventsRef = await collection(db, "events");
        const q = query(eventsRef, orderBy("created"));
        const snapShot = await getDocs(q);
        const eventsList: ArticleProps[] = [];
        snapShot.forEach((doc: DocumentData) => {
          return eventsList.push(doc.data());
        });
      };
    
    

    【讨论】:

      【解决方案3】:

      我的建议:

      1. 重命名 useState 钩子,因此两者之间的唯一区别是“set”和大写字母。

      2. 将函数重构为箭头函数,并使用 useCallback 钩子和 try/catch 对其进行优化。

      3. 假设它是一个你想要的数组,将它设置为 res.data 而不是映射它。

      4. 在 useEffect 中设置一个 if 语句,以免意外调用它超出你的需要。

      5. 通过将其映射到projects.map(project =&gt; ...),在您的退货中使用它

      代码格式建议:

      // Hooks
      const [projects, setProjects] = useState<Array | undefined>();
      
      // Arrow function for get projects
      const getProjects = useCallback(async () => {
        try {
          const res = await db.collection('projects').get();
          return setProjects(res.data);
        } catch {
          // Error here
          setProject([]);
        }
      }, []);
      
      useEffect(() => {
        if(!projects) {
          getProjects();
        }
      }, [projects]);

      【讨论】:

        猜你喜欢
        • 2018-03-27
        • 2017-06-24
        • 2021-08-05
        • 2020-11-18
        • 2020-05-23
        • 2018-10-26
        • 2021-01-03
        • 2020-07-24
        • 2021-06-30
        相关资源
        最近更新 更多