Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • 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?

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>
    );

>Solution :

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading