Bablo
Bablo

Reputation: 59

Handling events using UseState in React

I created 3 components: App, UserList & UserInfo. When I click on the button (get Users) I receive a list of users, how can I get user information when I click on each user in the list?

I read about event handling but I don't know how to apply it in this example.

App.js

import React, { useState } from 'react';
import './App.css';
import UserList from './components/UserList'
import UserInfo from './components/UserInfo'

function App() {
  const [users, setUsers] = useState([])


 async function getUsers(){
    try{
      const response = await fetch(`https://randomuser.me/api/?results=5`)
      if(!response.ok){
        throw Error('something went wrong during fetch API')
      }

      const data = await response.json()
      setUsers(data.results)
      console.log(data)

    } catch (error){
      console.log(error)

    }
  }


  return (
    <div className="App">

     <button onClick={()=> getUsers()}>Get Users</button>
     <UserList users={users}/>
    </div>
  );
}

export default App;

UserList.js

import React from 'react';
import uuid from 'uuid'

const UserList = ({users, onClickUser}) => {
    return (
        <div>
            <ul>
                {
                    users.map(user =>{
                        return(
                    <li key={uuid()} onClick={() => onClickUser(user) }>{user.name.first}</li>
                    ) 
                })}
            </ul>
        </div>
    );
};

export default UserList;

UserInfo.js

import React from "react";

const UserInfo = ({ information }) => {
  return (
    <div>
      <div>
        {information.name.first} {information.name.last}
      </div>
      <div>{information.email}</div>
      <div>{information.gender}</div>
    </div>
  );
};

export default UserInfo;

Upvotes: 0

Views: 131

Answers (1)

Matt Oestreich
Matt Oestreich

Reputation: 8528

You are extremely close to getting this working... Only that you are not using the onClickUser prop within your App component (aka you aren't passing it down).. Here is an example of how you can accomplish what you're after:

const { useState } = React;
const { render } = ReactDOM;

const UserList = ({ users, onClickUser }) => {
  return (
    <div>
      <ul>
        {users.map(user => {
          return (
            <li key={uuid()} onClick={() => onClickUser(user)} style={{cursor: 'pointer'}}>
              {user.name.first}
            </li>
          );
        })}
      </ul>
    </div>
  );
};

const UserInfo = ({ information }) => {
  return (
    <div>
      <div>
        {information.name.first} {information.name.last}
      </div>
      <div>{information.email}</div>
      <div>{information.gender}</div>
    </div>
  );
};

function App() {
  const [users, setUsers] = useState([]);
  const [clickedUser, setClickedUser] = useState("");

  async function getUsers() {
    try {
      const response = await fetch(`https://randomuser.me/api/?results=5`);
      if (!response.ok) {
        throw Error("something went wrong during fetch API");
      }

      const data = await response.json();
      setUsers(data.results);
      console.log(data);
    } catch (error) {
      console.log(error);
    }
  }

  const handleUserClick = user => {
    console.log(user);
    setClickedUser(user);
  };

  return (
    <div className="App">
      <button onClick={() => getUsers()}>Get Users</button>
      {users.length ? <p style={{marginBottom: '0px'}}>Click on a user to see user info</p> : ""}
      {/* THIS IS WHAT YOU HAD BEFORE: */}
      {/* <UserList users={users} /> */}
      <UserList users={users} onClickUser={handleUserClick} />
      {clickedUser ? <pre>{JSON.stringify(clickedUser, null, 2)}</pre> : ""}
    </div>
  );
}

function uuid() { // only here so this doesn't bomb out
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
    var r = (Math.random() * 16) | 0,
      v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>

Upvotes: 1

Related Questions