KYin
KYin

Reputation: 559

How to fix State that is persisting on pagination?

Hello beautiful people!

I'm building a MERN stack website and having a problem with this Edit Mode state:

enter image description here

-> How to reset the state and/or make the Edit button automatically hide when we move to other page?



Here's my code:

- 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

Answers (1)

dbuchet
dbuchet

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

Related Questions