I have created a book search react application that uses the openLibrary API to search for books. I have a form group that should submit a GET request either on a form submit or a button click.
My issue is that neither the button nor the form retrieves data when I submit it.
I tried moving the Button
component outside of the Form
component, and it worked as expected; however, it doesn't work when I move it back into the Form
component
I tried binding the functions, but when I click the button or hit the enter key to submit my API request, it doesn't work for some reason
can someone shed some light on what I am doing wrong, please?
Here is my code
App.js
import React, { Component } from "react";
import { Table, Form, FormGroup, Label, Input, Button } from "reactstrap";
import axios from "axios";
import "./App.scss";
class App extends Component {
constructor() {
super();
this.searchBooks = this.searchBooks.bind(this);
this.onChangeHandler = this.onChangeHandler.bind(this);
this.state = {
booksData: [],
searchQuery: "",
};
}
searchBooks = () => {
axios
.get(`http://openlibrary.org/search.json?title=${this.state.searchQuery}`)
.then((response) => {
const data = response.data.docs;
this.setState({
booksData: data,
searchQuery: "",
});
});
};
onChangeHandler = (event) => {
let searchQ = event.target.value;
searchQ = searchQ.replace(/\s /g, " ").toLowerCase();
this.setState({
...this.state,
searchQuery: searchQ,
});
};
render() {
return (
<div className="App">
<Form onSubmit={() => this.searchBooks}>
<FormGroup className="form-group container">
<Label for="search-field" id="search-label">
Search:{" "}
</Label>
<Input
id="search-field"
name="search books"
placeholder="Book Title"
type="input"
onChange={this.onChangeHandler}
></Input>
<Button
color="primary"
size="md"
className="search-btn"
type="submit"
onClick={() => this.searchBooks}
>
Search
</Button>
</FormGroup>
</Form>
<Table className="books-table container">
<thead>
<tr>
<th>Book Title</th>
<th>Book Author</th>
</tr>
</thead>
<tbody>
{this.state.booksData.map((book) => (
<tr key={book.key}>
<td>{book.title}</td>
<td>{book.author_name}</td>
</tr>
))}
</tbody>
</Table>
</div>
);
}
}
export default App;
App.scss
.page-title{
text-align: center;
margin-top: 25px;
margin-bottom: 30px;
}
.books-table{
margin-top: 20px;
}
.form-group{
display: flex;
flex-direction: row;
align-items: end;
justify-content: center;
margin-top: 30px;
.search-btn{
margin-left: 20px;
}
#search-field{
width: 40%;
}
#search-label{
margin-right: 20px;
}
}
CodePudding user response:
You should execute the this.searchBooks()
function inside the arrow function. But you didn't. You pass as a reference only therefore nothing executed.
You can either do onSubmit={this.searchBooks}
or onSubmit={()=> this.searchBooks()}
. If your searchBooks function take any parameter, the second approach is the way to go
CodePudding user response:
You use arrow function so you should execute or pass as a reference
onSubmit={()=> this.searchBooks()}
or
onSubmit={this.searchBooks}