'How to pass item's data to another component, edit data and save data in React.js?
I have a book table page to list all the books in the database, mapped with their book ID. If I click the book name, it will link to an edit book page, in this page, the input fields should be filled with the book detail, I can edit the book detail and save it in the database.
The problem is, how do I pass the book detail to another component?
Book table component
class BookTable extends Component {
constructor(props){
super(props)
this.state = {
books: [],
book: {}
}
render() {
return (
<div className='display-container'>
<div className="card-group-admin">
<div className="container">
<div className="row row-cols-3">
{this.state.books.map(book =>
<div className="card" style={{height:550 + 'px', width:320 + 'px'}} key={book._id}>
<img src={`http://localhost:3001/${book.bookImage}`} className="card-img-top" alt="comic book coverpage" />
<div className="card-body">
<Link to={`/books/${book._id}`} book={this.setState={book}}><h5 className="card-title">{book.bookName}</h5></Link>
<p className="card-text">{book.bookDescription}</p>
<div className="card-bottom-container">
<p className="card-status">{book.bookStatus}</p>
<button type="button" onClick={() => this.handleDeleteClick(book._id)}
className="btn btn-secondary" id="btnLength">Delete</button>
</div>
</div>
</div>)
}</div>
</div>
</div>
</div>
I am not sure whether "book={this.setState={book}}" inside the tag is correct or not, that's probably is where the problem at.
Edit component
import React, {useState} from 'react';
import { useHistory } from "react-router-dom";
import {book} from './BookTable';
function Edit ({book}) {
const [bookName, setBookName] = useState(book.bookName);
const [author, setAuthor] = useState(book.author);
const [publisher, setPublisher] = useState(book.publisher);
const [yearReleased, setYearReleased] = useState(book.yearReleased);
const [type, setType] = useState(book.type);
const [advancedBookType, setAdvancedBookType] = useState(book.advancedBookType);
const [rentalPrice, setRentalPrice] = useState(book.rentalPrice);
const [bookDescription, setBookDescription] = useState(book.bookDescription);
const handleSubmit = (e) => {
e.preventDefault();
const bookDetail = {
bookName,
author,
publisher,
yearReleased,
type,
advancedBookType,
rentalPrice,
bookDescription };
axios.put(`http://localhost:3001/app/books/${_id}`, bookDetail)
.then(response => {
console.log(response.data);
})
.catch(err => console.log(err));
}
const history = useHistory();
const handleBack = () => {
history.push("/adminDashboard");
}
return (
<div className="editPage">
<h1>Edit book page</h1>
<form onSubmit={handleSubmit} >
<label className="editLabel">Book name:</label>
<input type = 'text'
value={book.bookName}
onChange={(e) => setBookName(e.target.value)}
className="form-control form-group form-control-sm input" />
<label className="editLabel">Author:</label>
<input type = 'text'
value={book.author}
onChange={(e) => setAuthor(e.target.value)}
className="form-control form-group form-control-sm input" />
<label className="editLabel">Publisher:</label>
<input type = 'text'
value={book.publisher}
onChange={(e) => setPublisher(e.target.value)}
className="form-control form-group form-control-sm input" />
<label className="editLabel">Year released:</label>
<input type = 'number'
value={book.yearReleased}
onChange={(e) => setYearReleased(e.target.value)}
className="form-control form-group form-control-sm input" />
<label className="editLabel">Type:</label>
<select type = 'text'
value={book.type}
onChange={(e) => setType(e.target.value)}
className="form-control form-group form-control-sm input" id="exampleFormControlSelect1">
<option>Comedy</option>
<option>Love</option>
<option>Horror</option>
<option>Detecting</option>
<option>Fiction</option>
<option>Adventure</option>
<option>Action</option>
<option>Youth</option>
</select>
<label className="editLabel">Advanced book type:</label>
<select type = 'text'
value={book.advancedBookType}
onChange={(e) => setAdvancedBookType(e.target.value)}
className="form-control form-group form-control-sm input" id="exampleFormControlSelect1">
<option >None</option>
<option>Popular</option>
<option>New release</option>
</select>
<label className="editLabel">Rental price ($):</label>
<input type = 'number'
value={book.rentalPrice}
onChange={(e) => setRentalPrice(e.target.value)}
className="form-control form-group form-control-sm input" />
<label className="editLabel">Book description:</label>
<textarea value={book.bookDescription}
onChange={(e) => setBookDescription(e.target.value)}
className="form-control form-group textbox" rows="4">
</textarea>
<div className="buttonGroup">
<button onClick={() => handleBack()} className="btn btn-outline-dark">Back</button>
<input type="submit" className="btn btn-primary" id="right" value="Save" />
{/* <input type="reset" className="btn btn-outline-secondary" id="right" value="Delete" /> */}
</div>
</form>
</div>
);
}
export default Edit;
Backend book route
router.put('/books/:id', (request, response) => {
Book.findOneAndUpdate({ _id: request.params.id }, request.body, { new:true, useFindAndModify: false },
(err, book) => {
if (err) {
response.send(err);
}
response.json(book);
});
})
Solution 1:[1]
<Link to={{ pathname: `/books/${book._id}`, state: { data: book } }}> {book.bookName} </Link>
in Edit component
const { data } = props.location.state;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | aerials |