Reactjs:如何使用Reactjs在弹出按钮单击时从数据库中正确获取每个用户记录

问题描述 投票:0回答:2

下面的代码显示用户列表按钮单击的每个用户信息。现在我想从用户列表按钮点击数据库中获取每个用户记录。

在open()函数中,我已经实现了下面的代码

open = (id,name) => {
    alert(id);
    alert(name);

    //start axios api call

    const user_data = {
        uid: 'id',
        uname: 'name'
    };

    this.setState({ loading_image: true }, () => {
    axios.post("http://localhost/data.php", { user_data })  
           .then(response => {
               this.setState({
                   chatData1: response.data[0].id,
                   chatData: response.data,
                   loading_image: false
               });
                console.log(this.state.chatData);
                alert(this.state.chatData1);
           })
           .catch(error => {
             console.log(error);
           });
     });
}

在类OpenedUser()中,我在构造函数中初始化了下面的代码

 chatData: [] 

在render方法中已经实现了代码

<b> Load Message from Database for each user ({this.state.chatData1})</b>
<div>
 {this.state.chatData.map((pere, i) => (<li key={i}>{pere.lastname} - {pere.id}-----  {pere.username}</li>))}
</div>

这是我的问题:

我的问题是Axios Api正在获得结果但是在渲染方法中没有看到任何结果。但是我可以在控制台中按照以下代码看到它:Array(1)0:{id:“1”,firstname:“faco”,lastname:“facoyo”} length:1

这是json api响应的一个例子。

[{"id":"1","firstname":"faco","lastname":"facoyo"}]

这是完整的代码

import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import { Link } from 'react-router-dom';
import axios from 'axios';



class User extends React.Component {

  open = () => this.props.open(this.props.data.id, this.props.data.name);


  render() {

    return (
      <React.Fragment>
        <div key={this.props.data.id}>
          <button onClick={() => this.open(this.props.data.id,this.props.data.name)}>{this.props.data.name}</button>
        </div>
      </React.Fragment>
    );
  }
}


class OpenedUser extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
 chatData: [],

      hidden: false,
    };
  }





componentDidMount(){

} // close component didmount

  toggleHidden = () =>
    this.setState(prevState => ({ hidden: !prevState.hidden }));

  close = () => this.props.close(this.props.data.id);

  render() {

    return (
      <div key={this.props.data.id} style={{ display: "inline-block" }}>
        <div  className="msg_head">

          <button onClick={this.close}>close</button>
          <div>user {this.props.data.id}</div>
          <div>name {this.props.data.name}</div>
          {this.state.hidden ? null : (
            <div className="msg_wrap">
              <div className="msg_body">Message will appear here</div>



<b> Load Message from Database for each user ({this.state.chatData1}) </b>
<div>
 {this.state.chatData.map((pere, i) => (
              <li key={i}>
                {pere.lastname} - {pere.id}-----  {pere.username} 
              </li>
            ))}



          </div>



            </div>
          )}
        </div>
      </div>
    );
  }
}
class App extends React.Component {
  constructor() {
    super();

    this.state = {
      shown: true,
      activeIds: [],
      data: [
        { id: 1, name: "user 1" },
        { id: 2, name: "user 2" },
        { id: 3, name: "user 3" },
        { id: 4, name: "user 4" },
        { id: 5, name: "user 5" }
      ],
    };

  }






toggle() {
        this.setState({
            shown: !this.state.shown
        });
    }


  open = (id,name) => {

alert(id);
alert(name);

//start axios api call

const user_data = {
    uid: 'id',
    uname: 'name'
    };

this.setState({ loading_image: true }, () => {
axios.post("http://localhost/apidb_react/search_data.php", { user_data })

           .then(response => {
             this.setState({

         chatData1: response.data[0].id,
         chatData: response.data,
               loading_image: false
             });

console.log(this.state.chatData);
alert(this.state.chatData1);

           })
           .catch(error => {
             console.log(error);
           });

     });



// end axios api call


   this.setState((prevState) => ({
      activeIds: prevState.activeIds.find((user) => user === id)
        ? prevState.activeIds
        : [...prevState.activeIds, id]
    }));

  }

  close = id => {
    this.setState((prevState) => ({
      activeIds: prevState.activeIds.filter((user) => user !== id),
    }));
  };

  renderUser = (id) => {
    const user = this.state.data.find((user) => user.id === id);
    if (!user) {
      return null;
    }
    return (
      <OpenedUser key={user.id} data={user} close={this.close}/>
    )
  }




  renderActiveUser = () => {
    return (
      <div style={{ position: "fixed", bottom: 0, right: 0  }}>
        {this.state.activeIds.map((id) => this.renderUser(id)) }
      </div>
    );
  };


  render() {

    return (

      <div>



        {this.state.data.map(person => (
          <User key={person.id} data={person} open={this.open} />
        ))}
        {this.state.activeIds.length !== 0 && this.renderActiveUser()}
      </div>
    );
  }
}
reactjs
2个回答
0
投票

问题是你在App组件中发出请求并存储在状态中,但是你试图访问子组件中的状态,因此它永远不会实际读取数据。

要解决此问题,您需要通过道具传递聊天数据

      <OpenedUser
        chatData={this.state.chatData}
        key={user.id}
        data={user}
        close={this.close}
      />

注意:在我的runnable示例中,我已经用模拟api承诺替换了api端点。

const mockApi = () => {
  return new Promise((resolve, reject) => {
    const json = [{ id: "1", firstname: "faco", lastname: "facoyo" }];
    resolve(json);
  });
};

class User extends React.Component {
  open = () => this.props.open(this.props.data.id, this.props.data.name);
  render() {
    return (
      <React.Fragment>
        <div key={this.props.data.id}>
          <button
            onClick={() => this.open(this.props.data.id, this.props.data.name)}
          >
            {this.props.data.name}
          </button>
        </div>
      </React.Fragment>
    );
  }
}

class OpenedUser extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hidden: false
    };
  }

  componentDidMount() {} // close component didmount

  toggleHidden = () =>
    this.setState(prevState => ({ hidden: !prevState.hidden }));

  close = () => this.props.close(this.props.data.id);

  render() {
    return (
      <div key={this.props.data.id} style={{ display: "inline-block" }}>
        <div className="msg_head">
          <button onClick={this.close}>close</button>
          <div>user {this.props.data.id}</div>
          <div>name {this.props.data.name}</div>
          {this.state.hidden ? null : (
            <div className="msg_wrap">
              <div className="msg_body">Message will appear here</div>

              <b>
                {" "}
                Load Message from Database for each user ({this.state.chatData1}
                ){" "}
              </b>
              <ul>
                {this.props.chatData.map((pere, i) => (
                  <li key={i}>
                    {pere.lastname} - {pere.id}----- {pere.username}
                  </li>
                ))}
              </ul>
            </div>
          )}
        </div>
      </div>
    );
  }
}
class App extends React.Component {
  constructor() {
    super();

    this.state = {
      shown: true,
      chatData: [],
      activeIds: [],
      data: [
        { id: 1, name: "user 1" },
        { id: 2, name: "user 2" },
        { id: 3, name: "user 3" },
        { id: 4, name: "user 4" },
        { id: 5, name: "user 5" }
      ]
    };
  }

  toggle() {
    this.setState({
      shown: !this.state.shown
    });
  }

  open = (id, name) => {
    alert(id);
    alert(name);

    //start axios api call

    const user_data = {
      uid: "id",
      uname: "name"
    };

    // this.setState({ loading_image: true }, () => {
    //   axios
    //     .post("http://localhost/apidb_react/search_data.php", { user_data })

    //     .then(response => {
    //       this.setState({
    //         chatData1: response.data[0].id,
    //         chatData: response.data,
    //         loading_image: false
    //       });

    //       console.log(this.state.chatData);
    //       alert(this.state.chatData1);
    //     })
    //     .catch(error => {
    //       console.log(error);
    //     });
    // });

    this.setState({ loading_image: true }, () => {
      mockApi().then(data => {
        this.setState({
          chatData1: data[0].id,
          chatData: data,
          loading_image: false
        });
      });
    });

    // end axios api call

    this.setState(prevState => ({
      activeIds: prevState.activeIds.find(user => user === id)
        ? prevState.activeIds
        : [...prevState.activeIds, id]
    }));
  };

  close = id => {
    this.setState(prevState => ({
      activeIds: prevState.activeIds.filter(user => user !== id)
    }));
  };

  renderUser = id => {
    const user = this.state.data.find(user => user.id === id);
    if (!user) {
      return null;
    }
    return (
      <OpenedUser
        chatData={this.state.chatData}
        key={user.id}
        data={user}
        close={this.close}
      />
    );
  };

  renderActiveUser = () => {
    return (
      <div style={{ position: "fixed", bottom: 0, right: 0 }}>
        {this.state.activeIds.map(id => this.renderUser(id))}
      </div>
    );
  };

  render() {
    return (
      <div>
        {this.state.data.map(person => (
          <User key={person.id} data={person} open={this.open} />
        ))}
        {this.state.activeIds.length !== 0 && this.renderActiveUser()}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<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>
<div id="root"></div>

0
投票

我在你的代码中看到了一些遗漏点,即你使用的是没有ul的li,这是一种无效的标记,然后你有.username的映射,根据响应,它是未定义的字段,也可能引发错误。

© www.soinside.com 2019 - 2024. All rights reserved.