satyajit
satyajit

Reputation: 694

How to get the value of user input field using ReactJS?

i am trying to fetch api-data as per user input field. how to fetch the value of these data?

my api end-point like this "http://localhost:8000/api/p_list?search=" . whenever user input the value, endpoint is like this "http://localhost:8000/api/p_list?search=01" here is the input field value is "01". i want to get the value of the result.

i am probably new to reactjs. i tried something below like this but this is the static API url what i'm trying to fetch. i am not sure how to fetch dynamic url as per user input field.

it would be great if anybody could help me out what i am trying to solve. thank you so much in advance.


./src/productList.js

import React, {Component} from "react";
import Contacts from './productListHook.js';


export default class App  extends Component{

   state = {
       contacts: []
   }

   componentDidMount() {
       fetch('http://localhost:8000/api/p_list?search=')
       .then(res => res.json())
       .then((data) => {
         this.setState({ contacts: data })
       })
       .catch(console.log)
     }

   render(){
   return(

       <Contacts contacts={this.state.contacts} />
   )
}
}


./src/ProductListHook.js


import React from 'react'

    const Contacts = ({ contacts }) => {
      return (

        <section class="product_list section_padding">
        <div class="container">
            <div class="row">
                <div class="col-md-3">
                    <div class="product_sidebar">
                        <div class="single_sedebar">
                            <form action="#">
                                <input type="text" name="#" placeholder="Search keyword"/>
                                <i class="ti-search"></i>
                            </form>
                        </div>
                    </div>
                </div>
                <div class="col-sm-9">
                    <div class="product_list">
                        <div class="row">

                        {contacts.map((contact) => (

                            <div class="col-lg-3 col-md-9">
                                <div class="single_product_item">
                                    <img src={contact.image} alt="" class="img-fluid" />
                                    <h3> <a href={contact.url}>{contact.title}</a> </h3>
                                    <p>From ${contact.price}</p>
                                </div>
                            </div>

                            ))}

                        </div>
                        <div class="load_more_btn text-center">
                            <a href="#" class="btn_3">Load More</a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        </section>

      )
    };

export default Contacts

Upvotes: 0

Views: 855

Answers (2)

Khabir
Khabir

Reputation: 5844

Hi Please check this complete example: It is taking user id from user using the textbox and after button click it calls api with that user id and get all posts by that user. After that it shows all post title on the screen.

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

function PostListPageByUser() {
    const [posts, setPost] = useState([]);
    const [userId, setUserId] = useState([]);
    let signal = axios.CancelToken.source();

    function handleChange(event) {
        setUserId(event.target.value);
    }

    function handleClick(event) {
        axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`, {
            cancelToken: signal.token,
        })
            .then(res => {
                const posts = res.data;
                setPost(posts);
            }).catch(err => {
            console.log(err);
        });
    }
    return (
        <React.Fragment>
            <span>Enter User Id</span>
            <input type="text" onChange={handleChange}/>
            <button onClick={handleClick}>Get Posts By User</button>
            <ul>
                {
                    posts.map(post => <li key={post.id}>{post.title}</li>)
                }
            </ul>
        </React.Fragment>
    );
}
export default PostListPageByUser;

As per your comment on my answer I added this example with form submit:

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

function PostListPageByUser() {
    const [posts, setPost] = useState([]);
    const [userId, setUserId] = useState([]);
    let signal = axios.CancelToken.source();

    function handleChange(event) {
        setUserId(event.target.value);
    }

    function handleSubmit(event) {
        event.preventDefault();
        axios.get(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`, {
            cancelToken: signal.token,
        })
            .then(res => {
                const posts = res.data;
                setPost(posts);
            }).catch(err => {
            console.log(err);
        });
    }

    return (
        <form onSubmit={handleSubmit}>
            <span>Enter User Id</span>
            <input type="text" onChange={handleChange}/>
            <button type="submit">Get Posts By User</button>
            <ul>
                {
                    posts.map(post => <li key={post.id}>{post.title}</li>)
                }
            </ul>
        </form>
    );
}

export default PostListPageByUser;

Upvotes: 1

Andrew Ribeiro
Andrew Ribeiro

Reputation: 666

Your Contacts component has the input but the API call is being made in its parent App component.

What you need to do is pass another prop to Contacts that is a function that will be called everytime the input state inside Contacts change.

Example:

class App extends React.Component {
  ...

  search(inputValue){
    fetch(`http://localhost:8000/api/p_list?search=${inputValue}`)
    .then(res => res.json())
    .then((data) => {
      this.setState({ contacts: data })
    })
    .catch(console.log)
  }

  render() {
    <Contacts contacts={this.state.contacts} onSearch={search}/>
  }

Now inside Contacts component:

const Contacts = ({contacts, onSearch}) => {
  const [search, setSearch] = useState('');
  return (
    ...
    <input onChange={
           (e) => {
            setSearch(search);
            onSearch(e.currentTarget.value);
           }
         } value={search} .../>
    ...
   )
}

I just wrote the conceptual code to make it work, it's missing bind and the other specific implementation about your project.

I strongly recommend you to implement a logic inside onSearch function to delay the API call because it will be triggered in new letter typed in the input. This can overload the api.

Hope it helps.

Upvotes: 0

Related Questions