【问题标题】:load the data dynamically by id on button click in ReactJS在 ReactJS 中单击按钮时通过 id 动态加载数据
【发布时间】:2021-11-23 14:41:20
【问题描述】:
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')”。我是反应js的新手,不知道该怎么做。数据未按 id 点击按钮加载到下表中。第一个表数据加载正确。

【问题讨论】:

    标签: javascript reactjs react-native api fetch-api


    【解决方案1】:

    你可以这样做:

    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>

    【讨论】:

      【解决方案2】:

      如果您不熟悉 react,我强烈建议您使用钩子,但您可以在代码中做几件事:

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

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

      2- onClick 功能: 看法 因为您将需要 id 将其传递给 fetch 函数。不需要带风扇箭头功能的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>

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

      【讨论】:

      • 它也不行!
      • 我刚刚编辑了它,抱歉,它不能正常工作
      【解决方案3】:

      问题很少

      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

      【讨论】:

      • @Gaurav,看看这个!!
      • 只接受第一个id,不接受其他id,例如检查最后一个。
      • @Gaurav,最后一个 id 的 Api 响应为空。检查这个 => jsonplaceholder.typicode.com/users/200
      猜你喜欢
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      相关资源
      最近更新 更多