Search code examples
reactjsreact-hooksrendertsx

Values not update when back to page even though I have already updated them


I did a simple crud that consume a API with useEffect, but the problem appears when go to other page (no in my application, I've only one page) and back to my page.

Example:

enter image description here

I've these values and change to:

enter image description here

When I go to other page and back this page, the values appears like in first image.

Context file:

function loadApi(){
    fetch("http://localhost:8000/get-names")
        .then(response => response.json())
        .then(data => {setItems(data);console.log(data)})
}
    
useEffect(() => loadApi(),[])

const [items,setItems] = useState<ItemType[] | undefined>()

console.log("Items: "+ JSON.stringify(items))

const addItem = async (name: string) => {
    const response = await fetch("http://localhost:8000/insert-name",{
        method: "POST",
        body: JSON.stringify({name: name}),
        headers: {"content-type": "application/json"},
    })
    const data: ItemType = await response.json()
    if (items) setItems([...items,data])
    else setItems([data])
}

const removeItem = async (item: ItemType) => {
    const response = await fetch("http://localhost:8000/remove-name",{
        method: "DELETE",
        body: JSON.stringify({
            name: item.name,
            id: item.id
        }),
        headers: {"content-type": "application/json"},
    })
    const data: ItemType = await response.json()
    const newArray = items?.filter(el => el.id != item.id)
    setItems(newArray)
}

const editItem = async (name: string,item: ItemType) => {
    const response = await fetch("http://localhost:8000/update-name",{
        method: 'PUT',
        body: JSON.stringify({ 
            id: item.id,
            name: item.name,
            newName: name,            
        }),
        headers: {"content-type": "application/json"}
    })
    const data = await response.json()
    const newArray = items?.map(el => {
        el.name = el.id == item.id ? name : item.name;
        return el
    })
    setItems(newArray)
}

return(
    <ItemsContext.Provider value={{items,addItem,removeItem,editItem}}>
        {children}
    </ItemsContext.Provider>
)

App.tsx

  const [search, setSearch] = useState<string>("")
  const [addInput, setAddInput] = useState<string>("")
  const context = useContext(ItemsContext)

  const addItems = () => {
      if(addInput != ""){
        context?.addItem(addInput)
        setAddInput("")
      }
  }

  //@ts-ignore
  const enterKey = (e) => {
    if (e.key === 'Enter') {
      addItems()
    }
  }

return (
  <main>
      <nav>
        <input 
          id='searchInput'
          type="text"
          value={search}
          onChange={e => setSearch(e.target.value)}
        />
        <FaSearch className="inputButton" />
      </nav>  
      <section id='cardBox'>
        {context && context?.items?.map((item: ItemType) => {
          if (item.name.toLowerCase().includes(search.toLowerCase()) || search == ""){
            return <Card key={item.id} name={item.name} id={item.id}/>
          }
        })}
      </section>
      <div id='inputFooter'>
        <input 
          id='addInput'
          type="text"
          value={addInput}
          onChange={e => setAddInput(e.target.value)}
          onKeyDown={enterKey}
        />
        <IoIosAddCircle className="inputButton" onClick={() => addItems()}/>
      </div>
  </main>
)

How see in code, the console shows "item" and "data", but they has the first image value even after updating and coming back to page, but when reload page back to normal and consume the updated values.


Solution

  • Each time you call an API to modify your data on the backend, you need to call loadApi() to update the state with the new data from the db.

    For instance:

      const removeItem = async (item: ItemType) => {
            const response = await fetch("http://localhost:8000/remove-name",{
                method: "DELETE",
                body: JSON.stringify({
                    name: item.name,
                    id: item.id
                }),
                headers: {"content-type": "application/json"},
            })
            const data: ItemType = await response.json()
            const newArray = items?.filter(el => el.id != item.id)
            setItems(newArray);
            loadApi();
        }
    
        const editItem = async (name: string,item: ItemType) => {
            const response = await fetch("http://localhost:8000/update-name",{
                method: 'PUT',
                body: JSON.stringify({ 
                    id: item.id,
                    name: item.name,
                    newName: name,            
                }),
                headers: {"content-type": "application/json"}
            })
            const data = await response.json()
            const newArray = items?.map(el => {
                el.name = el.id == item.id ? name : item.name;
                return el
            })
            setItems(newArray);
            loadApi();
    
        }