在 ReactJS 中单击按钮时通过 id 动态加载数据

load the data dynamically by id on button click in ReactJS

import React,{Component} from 'react'

class Todo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      fetchdata: [],
    };
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.json())
      .then((json) => {
        this.setState({
          data: json,
        });
      });
  }

  componentDidUpdate(){
      this.fetchdata();
  }

fetchdata=()=>{
      fetch("https://jsonplaceholder.typicode.com/users/:id")
        .then((res) => res.json())
        .then((json) => {
          this.setState({
            fetchdata: json.data,
          });
        });
}

  render() {
    const { data, fetchdata } = this.state;
    return (
      <div>
        <div className="Todos row g-3">
          <table class="table col-auto">
            <thead>
              <tr>
                <th scope="col">Todo</th>
                <th scope="col">Title</th>
                <th scope="col">Status</th>
                <th scope="col">Action</th>
              </tr>
            </thead>
            <tbody>
              {this.state.data.map((data, index) => (
                <tr key={index}>
                  <th scope="row">{data.id}</th>
                  <td>{data.title}</td>
                  <td>{data.completed}</td>
                  <td>
                    <button onClick={this.fetchdata.bind(this, data)}>
                      View
                    </button>
                  </td>
                </tr>
              ))}
              ;
            </tbody>
          </table>
        </div>
        <div className="show-data col-auto">
          <table class="table table-striped">
            <thead>
              <tr>
                <th scope="col">Todo_Id</th>
                <th scope="col">Todo_title</th>
                <th scope="col">User_id</th>
              </tr>
            </thead>
            <tbody>
              {this.state.fetchdata.map((fetchdata, index) => (
                <tr key={index}>
                  <th scope="row">{fetchdata.id}</th>
                  <td>{fetchdata.name}</td>
                  <td>{fetchdata.email}</td>
                </tr>
              ))}
              ;
            </tbody>
          </table>
        </div>
      </div>
    );
  }
}

export default Todo

这是我的代码,我想在单击按钮时加载数据,但出现错误:“无法读取未定义的属性(读取 'map')”。我是 React js 的新手,不知道该怎么做。按 ID 单击按钮时,数据未加载到下方 table 中。第一个 table 数据正在正确加载。

几乎没有问题

  1. id 没有作为参数传递给 fetchdata
  2. 响应数据是 JSON 而不是 Array
  3. 请勿在未检查上一个状态的情况下调用 componentDidUpdate 中的任何函数。有一个无限循环调用 API.
  4. 不需要绑定 fetchdata 函数,因为它是一个箭头函数。
import React, { Component } from "react";

class Todo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      fetchdata: []
    };
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.json())
      .then((json) => {
        this.setState({
          data: json
        });
      });
  }

  fetchdata = (id) => {
    console.log(id);
    fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
      .then((res) => res.json())
      .then((json) => {
        console.log(json);
        this.setState({
          fetchdata: json
        });
      });
  };

  render() {
    const { data, fetchdata } = this.state;

    return (
      <div>
        <div className="Todos row g-3">
          <table class="table col-auto">
            <thead>
              <tr>
                <th scope="col">Todo</th>
                <th scope="col">Title</th>
                <th scope="col">Status</th>
                <th scope="col">Action</th>
              </tr>
            </thead>
            <tbody>
              {this.state.data.map((data, index) => (
                <tr key={index}>
                  <th scope="row">{data.id}</th>
                  <td>{data.title}</td>
                  <td>{data.completed}</td>
                  <td>
                    <button onClick={() => this.fetchdata(data.id)}>
                      View
                    </button>
                  </td>
                </tr>
              ))}
              ;
            </tbody>
          </table>
        </div>
        <div className="show-data col-auto">
          <table class="table table-striped">
            <thead>
              <tr>
                <th scope="col">Todo_Id</th>
                <th scope="col">Todo_title</th>
                <th scope="col">User_id</th>
              </tr>
            </thead>
            <tbody>
              {this.state.fetchdata && (
                <tr>
                  <th scope="row">{fetchdata.id}</th>
                  <td>{fetchdata.name}</td>
                  <td>{fetchdata.email}</td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    );
  }
}

export default Todo;

沙盒代码 => https://codesandbox.io/s/pensive-parm-c0l54?file=/src/App.js:0-2277

如果您是 React 新手,我强烈建议您使用钩子,但您可以在代码中做几件事:

1-获取数据(我认为你需要 id,所以):

fetchdata=(id)=>{ 获取(https://jsonplaceholder.typicode.com/users/${id}) .then((res) => res.json()) .then((json) => { this.setState({ 获取数据:json.data, }); }); } 这样你就可以通过参数传递 id。

2- onClick 函数: 看法 因为您需要将 id 传递给获取函数。不需要带扇形箭头功能的 bina

3- 这是我建议的钩子代码:

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

const Todo = () => {
  const [data, setData] = useState([])
  const [fetchdata,setFetchdata] = useState([])
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/todos")
    .then((res) => res.json())
    .then((json) => {
      setData(json);
    });
  },[])


  const fetchdataById = (id) => {
    console.log(id);
    fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
      .then((res) => res.json())
      .then((json) => {
        console.log(json);
        setFetchdata(json)
      });
  };

    return (
      <div>
        <div className="Todos row g-3">
          <table class="table col-auto">
            <thead>
              <tr>
                <th scope="col">Todo</th>
                <th scope="col">Title</th>
                <th scope="col">Status</th>
                <th scope="col">Action</th>
              </tr>
            </thead>
            <tbody>
              {data.map((data, index) => (
                <tr key={index}>
                  <th scope="row">{data.id}</th>
                  <td>{data.title}</td>
                  <td>{data.completed}</td>
                  <td>
                    <button onClick={() => fetchdataById(data.id)}>
                      View
                    </button>
                  </td>
                </tr>
              ))}
              ;
            </tbody>
          </table>
        </div>
        <div className="show-data col-auto">
          <table class="table table-striped">
            <thead>
              <tr>
                <th scope="col">Todo_Id</th>
                <th scope="col">Todo_title</th>
                <th scope="col">User_id</th>
              </tr>
            </thead>
            <tbody>
              {fetchdata && (
                <tr>
                  <th scope="row">{fetchdata.id}</th>
                  <td>{fetchdata.name}</td>
                  <td>{fetchdata.email}</td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    );
  }


export default Todo;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

像这样的东西应该可以工作,

您可以执行以下操作:

class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      fetchdata: {}
    };
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.json())
      .then((json) => {
        this.setState({
          data: json
        });
      });
  }

  fetchdata = (todo) => {
    fetch("https://jsonplaceholder.typicode.com/users/" + todo.id)
      .then((res) => res.json())
      .then((json) => {
        this.setState({
          fetchdata: json
        });
      });
  };

  render() {
    const { data, fetchdata } = this.state;
    return (
      <div>
        <div className="Todos row g-3">
          <table className="table col-auto">
            <thead>
              <tr>
                <th scope="col">Todo</th>
                <th scope="col">Title</th>
                <th scope="col">Status</th>
                <th scope="col">Action</th>
              </tr>
            </thead>
            <tbody>
              {data.map((todo, index) => (
                <tr key={index}>
                  <th scope="row">{todo.id}</th>
                  <td>{todo.title}</td>
                  <td>{todo.completed}</td>
                  <td>
                    <button onClick={() => this.fetchdata(todo)}>View</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <div className="show-data col-auto">
          <table className="table table-striped">
            <thead>
              <tr>
                <th scope="col">Todo_Id</th>
                <th scope="col">Todo_title</th>
                <th scope="col">User_id</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <th scope="row">{fetchdata.id}</th>
                <td>{fetchdata.name}</td>
                <td>{fetchdata.email}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    );
  }
}

ReactDOM.render(
  <Todo />,
  document.body
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>