类型错误:无法读取未定义的属性“参数”(React/TypeScript)

时间:2021-07-21 18:42:51

标签: reactjs typescript

enter image description here

SitePage.tsx

import { Component } from "react";
import { Link } from "react-router-dom";
import axios from "axios";

interface Props {
  id: any,
  site: any,
  match: any
}

export class SitePage extends Component<any> {
  state = {
    site: {},
    isLoaded: false
  }

  componentDidMount() {
    axios.get(process.env.REACT_APP_SITES_URL + `/${this.props.match.params.id}`)
      .then(res => this.setState({
        site: res.data,
        isLoaded: true
      }))
      .catch(err => console.log(err))
  }

  render() {
    const { site, isLoaded } = this.state;
    return (
      <>
        <Link to="/">Go Back</Link>
        {/* <h1>{ site[0].title }</h1> */}
      </>
    )
  }
}

export default SitePage

App.tsx

import { lazy, Suspense } from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { MessagingProvider } from "../context/messaging/MessagingContext";
import Auth0ProviderWithHistory from '../auth/Auth0ProviderWithHistory';
import Auth0Wrapper from "../auth/Auth0Wrapper";
import ErrorBoundary from "../../utils/components/ErrorBoundary";
import TopBar from "../navigation/TopBar";
import { LoadingBackdrop } from "../../utils/components/Backdrops";

const HomePage = (
  lazy(() => (
    import(/* webpackChunkName: "HomePage" */"./HomePage"))
  )
);

const Sites = (
  lazy(() => (
    import(/* webpackChunkName: "Sites" */"../sites/main/SitesMain"))
  )
);

const SitePage = (
  lazy(() => (
    import(/* webpackChunkName: "SitePage" */"../sites/main/SitePage"))
  )
);

const Projects = (
  lazy(() => (
    import(/* webpackChunkName: "Projects" */"../projects/main/ProjectsMain"))
  )
);

const App = (): JSX.Element => (
  <MessagingProvider>
    <Router>
      <Auth0ProviderWithHistory>
        <ErrorBoundary>
          <TopBar />
          <Suspense fallback={<LoadingBackdrop loading text="Loading Development Hub" />}>
            <Auth0Wrapper>
              <main className="container">
                <Routes>
                  <Route path="/" element={<HomePage />} />
                  <Route path="/sites" element={<Sites />}></Route>
                  <Route path="/sites/:id" element={<SitePage />}></Route>
                  <Route path="/projects" element={<Projects />}></Route>
                </Routes>
              </main>
            </Auth0Wrapper>
          </Suspense>
        </ErrorBoundary>
      </Auth0ProviderWithHistory>
    </Router>
  </MessagingProvider>
)

export default App;

SiteItem.tsx

import { Component } from 'react'
import { Link } from "react-router-dom";

interface Props {
  site: any,
}

export class SiteItem extends Component<Props> {
  render() {
    const {
      id,
      title,
      deployment_location,
      host,
      maintenance,
      protected_by_cloudflare,
      last_updated,
      assigned_to
    } = this.props.site;
    return (
      <div className="col-md-4">
        <div className="card shadow mb-4">
          <div className="card-body">
            <h5 className="card-title">
              <Link to={`/sites/${ id }`}>{ title }</Link>
            </h5>
            <div className="card mb-3">
              <table className="table table-borderless" style={{ marginBottom: "0px" }}>
                <tbody>
                  <tr className="border-bottom">
                    <th scope="row">Location</th>
                    <td>{ deployment_location }</td>
                  </tr>
                  <tr className="border-bottom">
                    <th scope="row">Hosted by us</th>
                    <td>{ host }</td>
                  </tr>
                  <tr className="border-bottom">
                    <th scope="row">Maintained by us</th>
                    <td>{ maintenance }</td>
                  </tr>
                  <tr className="border-bottom">
                    <th scope="row">Cloudflare Protected</th>
                    <td>{ protected_by_cloudflare }</td>
                  </tr>
                </tbody>
              </table>
            </div>
            <div className="card p-2 mb-3">
              <div>
                <p className="p-0 m-0">
                  <strong>Last Updated:</strong>
                  <span className="p-0 m-0"> { last_updated }</span>
                </p>
              </div>
            </div>
            <div className="card p-2 mb-3">
              <div>
                <p className="p-0 m-0">
                  <strong>Assigned To:</strong>
                  <span className="p-0 m-0"> { assigned_to }</span>
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

export default SiteItem

有谁知道是什么导致了这个问题?我认为我没有正确传递某些东西。

我试过搞乱道具,因为你可以看到一个界面,但我最终只使用了 <any> 路由看起来工作正常,但它没有正确获取 id。我也在这里搜索了很多次,但找不到可靠的答案。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我在这里得到的任何东西都没有那么有用,所以我经过大量研究后重新编写了代码。

这有效:

SitePage.tsx

import { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { LoadingBackdrop } from "../../../utils/components/Backdrops";
import axios from "axios";

const SitePage = (): JSX.Element => {
  const { id } = useParams();
  const [site, setSite] = useState(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(true);

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

  const getSiteData = () => {
    axios.get(process.env.REACT_APP_SITES_URL + `/${id}`)
      .then((res) => {
        setSite(res.data);
      })
      .catch(err => console.log(err))
  }

  if (site != null) {
    return (
      <>
        <Link to="/">Go Back</Link>
        <div className="row mt-3">
          <div className="col-12">
            <div className="card shadow">
              <div className="card-body">
                <h1 className="card-title">{site.title}</h1>
                <div className="card p-2 mb-3">
                  <p className="m-0 p-0">
                    <strong>Deployment Location: </strong>
                    {site.deployment_location}
                  </p>
                  <p className="m-0 p-0">
                    <strong>Hosted by us: </strong>
                    {site.host}
                  </p>
                  <p className="m-0 p-0">
                    <strong>Maintained by us: </strong>
                    {site.maintenance}
                  </p>
                  <p className="m-0 p-0">
                    <strong>Cloudflare Protected: </strong>
                    {site.protected_by_cloudflare}
                  </p>
                </div>
                <div className="card p-2 mb-3">
                  <p className="m-0 p-0">
                    <strong>PHP Version: </strong>
                    {site.php_version}
                  </p>
                  <p className="m-0 p-0">
                    <strong>WP Version: </strong>
                    {site.wordpress_version}
                  </p>
                  <p className="m-0 p-0">
                    <strong>Last Updated: </strong>
                    {site.last_updated}
                  </p>
                </div>
                <div className="card p-2 mb-3">
                  <p className="m-0 p-0">
                    <strong>Git Location: </strong>
                    {site.git_location}
                  </p>
                  <p className="m-0 p-0">
                    <strong>DB Location: </strong>
                    {site.database_location}
                  </p>
                </div>
                <h3 className="pb-2">Notes</h3>
                <div dangerouslySetInnerHTML={{ __html: site.notes }} className="card p-2 mb-3"></div>
                <h3 className="pb-2">Logs</h3>
              </div>
            </div>
          </div>
        </div>
      </>
    );
  } else {
    return (
      <LoadingBackdrop loading={loading} text="Loading Site" />
    )
  }
}

export default SitePage;