Машинопись с маршрутизаторами React

#reactjs #typescript #react-router

#reactjs #typescript #react-маршрутизатор

Вопрос:

Я новичок в typescript и react. Я использую react-router-dom для создания маршрутов в моем приложении react. Я могу напрямую использовать /posts в качестве жестко заданного значения, но я хочу попробовать относительные пути для извлечения сообщений. Я добавил приведенный ниже код. Не могли бы вы, пожалуйста, сказать мне, как я могу исправить тип PostsPropsType?

Posts.tsx —

 import styles from "./Posts.module.css";
import { Link, RouteComponentProps } from "react-router-dom";
 
export type postType = {
  title: string;
  author: string;
  id: string;
};
 
type PostsPropsType = {
  postsData: postType[];
  postClick: Function;
} amp; RouteComponentProps;
 
export default function Posts(props: PostsPropsType) {
  const posts = props.postsData.map((post: postType, index: number) => {
    return (
      <Link to={`/${props.match.url}/${post.id}`}>
        <div
          className={styles.Post}
          key={index}
          onClick={() => props.postClick(post.id)}
        >
          <h3>
            <strong>{post.title}</strong>
          </h3>
          <div className={styles.Author}>{post.author}</div>
        </div>
      </Link>
    );
  });
  return <div className={styles.Posts}>{posts}</div>;
}
  

App.tsx —

 import React, { useState, useEffect } from "react";
import styles from "./App.module.css";

import Posts from "../components/Posts/Posts";
import { postType } from "../components/Posts/Posts";
import FullPost from "../components/FullPost/FullPost";
import { fullPostType } from "../components/FullPost/FullPost";
import NewPost from "../components/NewPost/NewPost";
import { BrowserRouter, Link, Route, Switch, Router } from "react-router-dom";

import jpaxios from "../apis/jsonplaceholder.axios";

export default function App(props: {}) {
  let [postsState, setPostsState] = useState<postType[]>();
  let [fullPostState, setFullPostState] = useState<fullPostType>({
    id: "0",
    body: "body",
    title: "Title",
  });

  useEffect(() => {
    jpaxios.get<postType[]>("/posts").then((response) => {
      const postsData = response.data.slice(0, 3);
      const posts = postsData.map((post: postType) => {
        return { title: post.title, author: "katsura", id: post.id };
      });
      setPostsState(posts);
    });
  }, []);

  const fullPostButtonHandler = (id: string) => {
    fullPostState?.id !== id amp;amp;
      jpaxios.get<fullPostType>(`/posts/${id}`).then((response) => {
        setFullPostState({
          id: id,
          body: response.data.body,
          title: response.data.title,
        });
      });
  };

  const fullPostDeleteHandler = (id: string) => {
    id !== "0" amp;amp;
      setFullPostState({
        id: "0",
        body: "body",
        title: "title",
      });
  };

  let postsElement = <div>Loading...</div>;
  if (postsState) {
    postsElement = (
      <Posts postsData={postsState} postClick={fullPostButtonHandler} />
    );
  }

  return (
    <BrowserRouter>
      <div className={styles.APP}>
        <ul>
          <li>
            <Link to="/new-post">New Post</Link>
          </li>
          <li>
            <Link to="/posts">Posts</Link>
          </li>
          <li>
            <Link to="/full-post">Full Post</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/posts" exact render={() => postsElement} />
          <Route path="/new-post" exact component={NewPost} />
        </Switch>
        <Route
          path={["/full-post", "/posts/:id"]}
          exact
          render={() => (
            <FullPost
              fullPost={fullPostState}
              deleteHandler={fullPostDeleteHandler}
            />
          )}
        />
      </div>
    </BrowserRouter>
  );
}
  

И ошибка, с которой я сталкиваюсь, заключается в —

 TypeScript error in /Users/parth/Documents/personal-git/react-playbook/axios-with-hooks/src/containers/App.tsx(54,8):
Type '{ postsData: postType[]; postClick: (id: string) => void; }' is missing the following properties from type 'RouteComponentProps<{}, StaticContext, UnknownFacade>': history, location, match  TS2739

    52 |   if (postsState) {
    53 |     postsElement = (
  > 54 |       <Posts postsData={postsState} postClick={fullPostButtonHandler} />
       |        ^
    55 |     );
    56 |   }
    57 | 
  

Ответ №1:

render Реквизиту Route передаются история, местоположение и объекты соответствия. В настоящее время вы не пересылаете их вместе с Posts , как того требует PostsPropsType . Итак, вместо этого:

 let postsElement = <div>Loading...</div>;
if (postsState) {
  postsElement = (
    <Posts postsData={postsState} postClick={fullPostButtonHandler} />
  );
}

// ...

render={() => postsElement}
  

Сделайте это:

 render={(routeProps) => (
  postsState ? (
    <Posts {...routeProps} postsData={postsState} postClick={fullPostButtonHandler} />
  ) : (
    <div>Loading...</div>
  )
)}