简体   繁体   中英

How do I change only the individual div of the onClick function to display more information?

I'm trying to make a function that displays more details about the user when the "Details" button is clicked. However, the button changes state for every div class. I want to limit this to only affect the div that contains the "Details" button. I included a screenshot of what it looks like right now with basic styling. I'd appreciate any other feedback as I'm very new to React.

import React, {Component} from 'react';
import './App.css';

class User extends Component {
  constructor(props) {
    super(props);
    this.state = { isVerified: false, users: []}
  }

  componentDidMount() {
    this.fetchData();
  }

  fetchData() {
    fetch ('https://randomuser.me/api?results=50')
    .then(response => response.json())
    .then(parsedJSON => parsedJSON.results.map(contact => (
      {
        id: `${contact.login.uuid}`,
        username: `${contact.login.username}`,
        firstname: `${contact.name.first}`,
        lastname: `${contact.name.last}`,
        pic: `${contact.picture.thumbnail}`,
        phone: `${contact.cell}`,
        city: `${contact.location.city}`,
        lat: `${contact.location.coordinates.latitude}`,
        long: `${contact.location.coordinates.longitude}`
      }
    )))
    .then(users => this.setState(
      {
        users,
        isVerified: false,
        viewDetails: false
      }
    ))
    .catch(error => console.log("parsing failed", error))
  }

//This is the  method that's changing state and showing details for every random user/profile div
  viewUserDetails = () => {
    console.log('view details toggle button here')
    this.setState({showDetails: !this.showDetails})
  }

  render() { 
    const {isVerified, users, showDetails} = this.state;
    return ( 
      <div>
        <header>
          <h1>Your Contacts</h1><br></br>
          Verify Friends for Offline Use
          </header>
          <div className="container">
            {users.map(userInfo => {
              const {id, username, firstname, lastname, pic, phone, city, lat, long} = userInfo;
              return (
                <div key={userInfo.id} title={userInfo.username} className="user-profile">
                  {!this.state.showDetails ? (
                  <div className="basic-userInfo">
                    {firstname} {lastname}
                    <img src={pic} alt={username} className="user-thumbnail-basic"></img>
                    <button className="details-button" onClick={this.viewUserDetails}>Details</button>
                  </div>
                  ) : (
                  <div className="detailed-userInfo">
                    {firstname} {lastname}
                    <img src={pic} alt={username} className="user-thumbnail-detailed"></img>
                    <ul>
                      <li>{username}</li>
                      <li>{phone}</li>
                      <li>{city}</li>
                    </ul>
                  </div>
                  )}
                </div>
              )
            })}
          </div>
      </div>
     );
  }
}

export default User;

preview before details button is clicked

The way you are using state right now is not going to accomplish what you want. You don't have the showDetails state scoped to a user in any way. If you wanted to scope it to an individual user, you could give your button an id property that is the user's id, like this:

 <button id={user.id} className="details-button" onClick={this.viewUserDetails}>Details</button>

Then, you could pass the click event to your viewUserDetails function, and instead of storing showDetails as a boolean, you could make it a user's id, like this:

 viewUserDetails = event => { console.log('view details toggle button here') this.setState({showDetails: event.target.id}) }

Then, instead of checking if showDetails is true, you could check if it equals the user's id:

 ... {this.state.showDetails?== id ? (

Of course, that would only let you view details for one user at a time. If you want to be able to view details for any number of users, you could instead store showDetails as an array of ids, and check if it.includes() the user's id.

Create a sub-component user that has its own showDetails state and then map Users to that sub component.

Here is a sandbox so you can play with it, kindly read the explanations on the code, good luck! - https://codesandbox.io/s/condescending-cache-wdeyv

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM