无法将值发送到另一个页面以做出反应

Cant send a value to another page in react

抱歉,如果这是最基本的,但我无法完成相当简单的任务。我有一个页面,其中我将数据从 API 呈现到卡片中,例如分区。例如:

<div class="card bg-light mb-3 offset-md-4" style={{ width: "30rem" }}>
  <div class="card-body">
    <h5 class="card-title">
      {post.userDetails != undefined ? post.userDetails.name : ""}
    </h5>
    <p class="card-text">{post.emailAddress}</p>
    <p class="card-text">
      {post.userDetails != undefined ? post.userDetails.phone : ""}
    </p>
  </div>
</div>;

对于每个数据项,屏幕上都会显示一张卡片。我正在尝试找到一种方法来单击其中一张卡片并在另一个页面上显示数据,我可以在该页面上编辑/删除所选卡片的数据,但我未能成功。以下是我的完整代码:

import React, { Component, useState, useEffect } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import axios from "axios";
import { URL } from "../Data/Env";

export default class UserPanel extends Component {
  constructor(props) {
    super(props);
    this.state = {
      post: [],
    };
  }
  componentDidMount() {
    this.getUser();
  }
  async getUser() {
    let url = URL.concat("authors");
    axios
      .get(url)
      .then((response) => {
        console.log(response.data);
        if (response.data.statusCode == 200) {
          this.setState({ post: response.data.data });
        } else if (response.data.statusCode == 400) {
          console.log("User detail retrieving failed !!");
        } else {
          console.log("User detail unknown error !!");
        }
      })
      .catch((error) => {});
  }
  showUser(post) {
    return (
      <div>
        <Link
          to={{ pathname: "/UserDetail", state: [{ userId: post.userId }] }}
        >
          <div
            class="card bg-light mb-3 offset-md-4"
            style={{ width: "30rem" }}
          >
            <div class="card-body">
              <h5 class="card-title">
                {post.userDetails != undefined ? post.userDetails.name : ""}
              </h5>
              <p class="card-text">{post.emailAddress}</p>
              <p class="card-text">
                {post.userDetails != undefined ? post.userDetails.phone : ""}
              </p>
            </div>
          </div>
        </Link>
      </div>
    );
  }
  render() {
    const { post } = this.state;
    return (
      <div>
        <br />
        <br />
        <div>
          <div className="row col-md-12">
            <div className="offset-md-4">
              {" "}
              <h3>All Users</h3>{" "}
            </div>
            <div>
              <Link to={"/SignUp"}>
                <button
                  className="btn btn-success"
                  style={{ marginLeft: "146px", width: "234px" }}
                >
                  {" "}
                  Add User
                </button>
              </Link>
            </div>
          </div>
          <br />
        </div>
        <div> {post.map(this.showUser)}</div>
      </div>
    );
  }
}

非常感谢任何帮助。

你不应该在 <Router> 之外使用 <Link>。首先你需要创建路由,然后你可以使用 <Link> 导航到相关页面。最好有与每条路线相关的单独组件。请参阅 link 以获取来自 react-router 的基本路由示例:https://reactrouter.com/web/guides/quick-start

对于 OP 的场景,必须有单独的 UsersUserDetail 组件,其中 Users 组件显示所有用户详细信息, UserDetail 组件显示选定的用户详细信息。 UserPanel 主要组件将用于包含应用程序的路由,例如 /UserDetail/SignUp.

以下实现可用作对 OP 场景的支持 material。在这种情况下,为了便于理解,从 api 获取的数据已被模拟。

UserPanel.js

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import UserDetail from "./UserDetail";
import Users from "./Users";

export default class UserPanel extends Component {
  render() {
    return (
      <div>
        <Router>
          <br />
          <br />
          <div>
            <div className="row col-md-12">
              <div className="offset-md-4">
                {" "}
                <h3>All Users</h3>{" "}
              </div>
              <div>
                <Link to={"/SignUp"}>
                  <button
                    className="btn btn-success"
                    style={{ marginLeft: "146px", width: "234px" }}
                  >
                    Add User
                  </button>
                </Link>
              </div>
            </div>
            <br />
          </div>

          <Route exact path="/" component={Users} />
          <Route exact path="/UserDetail" component={UserDetail} />
        </Router>
      </div>
    );
  }
}

Users.js

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

const users = [
  {
    userId: 1,
    userDetails: { name: "john", phone: "111232" },
    emailAddress: "john@gmail.com",
  },
  {
    userId: 2,
    userDetails: { name: "kamal", phone: "2222" },
    emailAddress: "kamal@gmail.com",
  },
];

export default class Users extends Component {
  constructor(props) {
    super(props);
    this.state = {
      posts: [],
    };
  }
  componentDidMount() {
    this.getUser();
  }
  async getUser() {
    await Promise.resolve(users).then((data) => this.setState({ posts: data }));
    /*
    mocked data fetching needs to be replaced with actual api invokation
    */
  }
  showUser(post) {
    return (
      <div>
        <div class="card bg-light mb-3 offset-md-4" style={{ width: "30rem" }}>
          <div class="card-body">
            <Link to={{ pathname: "/UserDetail", state: { post } }}>
              <h5 class="card-title">
                {post.userDetails != undefined ? post.userDetails.name : ""}
              </h5>
            </Link>
            <p class="card-text">{post.emailAddress}</p>
            <p class="card-text">
              {post.userDetails != undefined ? post.userDetails.phone : ""}
            </p>
          </div>
        </div>
      </div>
    );
  }
  render() {
    const { posts } = this.state;
    return <div> {posts.map(this.showUser)}</div>;
  }
}

UserDetail.js

import React from "react";
import { useLocation } from "react-router-dom";

const UserDetail = () => {
  const location = useLocation();
  const { post } = location.state;

  return (
    <div class="card bg-light mb-3 offset-md-4" style={{ width: "30rem" }}>
      <div class="card-body">
        <h5 class="card-title">
          {post.userDetails != undefined ? post.userDetails.name : ""}
        </h5>
        <p class="card-text">{post.emailAddress}</p>
        <p class="card-text">
          {post.userDetails != undefined ? post.userDetails.phone : ""}
        </p>
      </div>
    </div>
  );
};

export default UserDetail;

以下是相关路线的申请视图

路线:/

路由:/UserDetail

在上面的实现中,每张卡片的标题(用户名)已被link编辑到显示用户详细信息的/UserDetail 路由。 /SignUp 路由不包含组件,但它可以路由到特定的 child 组件,类似于 UsersUserDetail 组件。

useLocation 来自 react-router-dom 的钩子用于获取与当前 URL 相关的位置 object。从中可以提取位置状态

建议

  1. 由于从api获取的数据是objects的数组,所以将其存储为posts而不是 post。注意变量命名。

  2. 避免使用showUser(post)等函数将JSX元素引入render方法。直接引入组件如下。

        {posts.map((post) => (
          <div>
            <div
              class="card bg-light mb-3 offset-md-4"
              style={{ width: "30rem" }}
            >
              <div class="card-body">
                <Link to={{ pathname: "/UserDetail", state: { post } }}>
                  <h5 class="card-title">
                    {post.userDetails != undefined ? post.userDetails.name : ""}
                  </h5>
                </Link>
                <p class="card-text">{post.emailAddress}</p>
                <p class="card-text">
                  {post.userDetails != undefined ? post.userDetails.phone : ""}
                </p>
              </div>
            </div>
          </div>
        ))}
  1. 以可重用的格式创建 React 组件。 (甚至我已经在 UsersUserDetail 组件中复制了卡片组件的详细信息。最好将 child 组件作为 CardDetails 来重复使用它)