-1

I am trying to use useState hook and set the state after API call, but no matter how much time it never updates.

I want to use that state in other component using useContext. Now I only want my route to it when my state gets updated. How to achieve it?

My code:

const [openedFeedback, setOpenedFeedback] = useState<ProductRequest>({id: 0, title: '', category: '', upvotes: 0, status: '', description: '', comments: []})

const getFeedbackById = async (id: number) => {
    const url = `${host}api/product-requests/${id}`
    const response = await fetch(url, {
      method: 'GET', // *GET, POST, PUT, DELETE, etc.
      mode: 'cors', // no-cors, *cors, same-origin
      headers: {
        'Content-Type': 'application/json',
      }
    });

    const json = await response.json()
    
    setOpenedFeedback(json);
  }

The code for routing, triggers on click:

const openFeedback = async (id: number) => {
    await getFeedbackById(id)
    router.push('/components/feedback-detail')
  }

Other component:

import Link from 'next/link'
import React, { useContext, useEffect } from 'react'
import './FeedbackDetails.scss'
import FeedbackContent from '../FeedbackContent'
import FilterContext from '@/app/context/filters/FilterContext'

export default function FeedbackDetails() {

  const { openedFeedback } = useContext(FilterContext)
  
  useEffect(() => {
    setFeedback(openedFeedback)
    console.log(feedback);
    
  }, [openedFeedback])

  return (
    <div className='outer-container'>
      <div className="inner-container">
        <div className="btns-container">
          <Link href='/' className='back-btn'>
            <svg width="7" height="10" xmlns="http://www.w3.org/2000/svg"><path d="M6 9L2 5l4-4" stroke="#4661E6" strokeWidth="2" fill="none" fillRule="evenodd" /></svg>
            <span>Go Back</span>
          </Link>
          <Link href='/' className='edit-btn'>Edit Feedback</Link>
        </div>
        <div className="content-container">
          <FeedbackContent id={openedFeedback.id} title={openedFeedback.title} category={openedFeedback.category} upvotes={openedFeedback.upvotes} comments={openedFeedback.comments} description={openedFeedback.description} status={openedFeedback.status} />
        </div>
      </div>   
    </div>
  )
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Love S
  • 1
  • 3
  • Does this answer your question? [The useState set method is not reflecting a change immediately](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately) – jonrsharpe Aug 27 '23 at 08:22
  • No @jonrsharpe, it doesn't – Love S Aug 27 '23 at 08:35

2 Answers2

0

setState is a async function it will not log it directly instead use

useEffect(()=>console.log(<stateName>),[<stateName>])

to check the results and log it.

Ram Pandey
  • 23
  • 9
  • I am moving to other route ```await getFeedbackById(id) router.push('/components/feedback-detail')``` but there I cannot see updated variables, how to handle that, what should I use in useEffect in other component – Love S Aug 27 '23 at 08:14
  • The state will only be available for the component it is defined in not for other components. If you want to use it for other components you will have to integrate a global state management service like react context, redux or zustand. – Ram Pandey Aug 27 '23 at 08:18
  • I am using ```useContext``` and getting that state to other components – Love S Aug 27 '23 at 08:20
  • In the code there is no useContext mention. Cant guess the reason why its not working. Also you are not setting the context value here, atleast in the code you have provided – Ram Pandey Aug 27 '23 at 08:22
  • updated the code, sorry – Love S Aug 27 '23 at 08:25
  • You are not setting the context state in getFeedbackId function. – Ram Pandey Aug 27 '23 at 08:29
  • I am setting it. – Love S Aug 27 '23 at 08:40
0

You can use useSelector() hook to read the updated state in all components' of the application.

If required state field is state.apiResponse, useSelector(state.apiResponse) will serve the updated value to all components.

Note: Don't forget to dispatch action to set updated response to state after api call.