Reputation: 694
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
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
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