Reputation: 559
Hello beautiful people!
I'm building a MERN stack website and having a problem with this Edit Mode state:
When I click on the Edit button, it will set the Edit mode to true
and display the input field.
I click on the Edit button again to set the Edit mode to false
and hide the input field.
But if I don't change the Edit mode's state to false
and go to the next page - The input field will display on the same row number on the next page but cleared out the previous input.
The Update (Checkmark) button and other buttons in the rows work fine
-> How to reset the state and/or make the Edit button automatically hide when we move to other page?
- Pagination:
export default function Pagination({ foodPerPage, totalFood, paginate, currentPage }) {
const pageNumbers = []
for (let i = 1; i <= Math.ceil(totalFood / foodPerPage); i++) {
pageNumbers.push(i)
}
return (
<nav aria-label="Pagination" className="pagination">
<ul>
{pageNumbers.map(number => (
<li key={number} className="page-item">
<button
className={(currentPage === number ? "page-link active" : "page-link")}
onClick={() => paginate(number)}
>
{number}
</button>
</li>
))}
</ul>
</nav>
);
}
- App.js
export default function DinnerIdeas() {
const [foodList, setFoodList] = useState([])
const [searchedFood, setSearchedFood] = useState([])
const [noResult, setNoResult] = useState(false)
// Display food list:
useEffect(() => {
let unmounted = false
Axios.get("https://my-project.herokuapp.com/read")
.then((response) => {
if (!unmounted) {
setFoodList(response.data)
}
})
.catch(error => {
console.log(`The error is: ${error}`)
return
})
return () => {
unmounted = true
}
}, [foodList])
// Paginate states:
const [currentPage, setCurrentPage] = useState(1)
const [foodPerPage] = useState(5)
// Get current food:
const indexOfLastFood = currentPage * foodPerPage
const indexOfFirstFood = indexOfLastFood - foodPerPage
const currentFood = foodList.slice(indexOfFirstFood, indexOfLastFood)
const currentSearchedFood = searchedFood.slice(indexOfFirstFood, indexOfLastFood)
const paginate = (pageNumber) => {
setCurrentPage(pageNumber)
}
return (
<section>
{noResult ? <ResultNotFound/>
:
<FoodListTable
foodList={foodList}
currentFood={currentFood}
searchedFood={searchedFood}
currentSearchedFood={currentSearchedFood}
totalFood={foodList.length}
totalSearchedFood={searchedFood.length}
currentPage={currentPage}
paginate={paginate}
noResult={noResult}
foodPerPage={foodPerPage}
/>
}
</section>
)
}
- FoodListTable.js
import FoodListRow from './FoodListRow'
import Pagination from "../Pagination"
export default function FoodListTable(props) {
return (
<div className="flist container">
<table>
<thead>
<tr>
<th>
Food name
</th>
<th>Price</th>
<th>
Action
</th>
</tr>
</thead>
<tbody>
{props.searchedFood.length > 0 ? props.currentSearchedFood.map((val, key) => {
return (
<FoodListRow
val={val}
key={key}
foodName={val.foodName}
isVegetarian={val.isVegetarian}
priceRange={val.priceRange}
foodUrl={val.foodUrl}
/>
)
}) : props.currentFood.map((val, key) => {
return (
<FoodListRow
val={val}
key={key}
foodName={val.foodName}
isVegetarian={val.isVegetarian}
priceRange={val.priceRange}
foodUrl={val.foodUrl}
/>
)
})
}
</tbody>
</table>
{props.searchedFood.length > 0 ?
<Pagination foodPerPage={props.foodPerPage} totalFood={props.totalSearchedFood} paginate={props.paginate} currentPage={props.currentPage} />
:<Pagination foodPerPage={props.foodPerPage} totalFood={props.totalFood} paginate={props.paginate} currentPage={props.currentPage} />
}
</div>
)
}
- FoodListRow Component inside <FoodListTable/>
export default function FoodListRow(props) {
// Edit mode:
const [editBtn, setEditBtn] = useState(false)
const handleEdit = () => {
setEditBtn(!editBtn)
}
return (
<tr key={props.val._id}>
<td>
{props.val.foodName}
// Display the input field on Edit mode:
{editBtn &&
<div>
<input
type="text"
name="edit"
placeholder="New food name.."
autoComplete="off"
onChange={(event) => {setNewFoodName(event.target.value)}}
/>
<button
onClick={() => updateFoodName(props.val._id)}
>
✓
</button>
</div>
}
</td>
<td>{props.val.priceRange}</td>
<td>
<a
href={props.val.foodUrl}
className="flist__table--btn"
target="_blank"
rel="noopener noreferrer"
>
🔗
</a>
<button
onClick={handleEdit}
>
✏️
</button>
<button
onClick={() => deleteFood(props.val._id)}
>
❌
</button>
</td>
</tr>
);
Upvotes: 0
Views: 452
Reputation: 1651
Error must be on the code you've not share: FoodListTable
You probably map to render your FoodListRow
using the map index as a key
.
SO when you change your page from Pagintion, the key
stays the same across render and your inner state is not changed.
So either use something else as key for FoodListRow
(for exemple a database ID) or include your current page pagination in your key
Upvotes: 1