skip to Main Content

I’m working trying to add an object created from data returned in an AXIOS request to state in a React Application.

The object itself appears to be fine and even prints out as expected without errors but when I go to add it to a hook, nothing happens regardless of what code I use. I’ve tried several combinations and approaches, most of them can be seen in this older post from a couple of years ago which seems to describe the same thing that I’m trying to do. nearly every post or bit of information I’ve found so far suggests doing something much like this but nothing has done the trick.

I’ve attached my code below showing the entire function and the hook in question.

    const [queryResultData, setQueryResultData] = useState([])

    function queryResultDataHandler(resultData){
        for(let i=0; i < resultData.length; i++){
            const data=resultData[i];
            let book={
                title: data.title,
                publisher: data.publisher,
                copyright: data.publishedDate
            }
            setQueryResultData([...queryResultData,book]);
        }
    }

I’ve also included a screenshot showing the contents of each object and the array of data after each attempt to add the data.
enter image description here

Any input on why this is happening would be greatly appreciated as I can’t see what I’m doing wrong here.

2

Answers


  1. If you want to update some piece of state and it depends on the current state, you should always use the setState((previousState) => newState) function.

    In your case, you need to change:

    setQueryResultData([...queryResultData,book]);

    to

    setQueryResultData((oldQueryResultData) => [...oldQueryResultData, book]);

    You can read about this special behavior of the setState function returned by the useState() hook in the Official React Docs under the Parameters > nextState

    Login or Signup to reply.
  2. Alternatively to @Oscar Arranz’s answer, you better transform whole the array and append it once:

    const [queryResultData, setQueryResultData] = useState([])
    
    function queryResultDataHandler(resultData){
        const transformedData = resultData.map(({ 
          title, 
          publisher, 
          publishedDate 
        }) => ({
          title,
          publisher,
          copyright: publishedDate
        }))
        setQueryResultData([...queryResultData, ....transformedData]);
    }
    

    This will trigger re-rendering just once. While calling setQueryResultData for many times should – at least if I recall correctly – trigger multiple waste re-renders.

    PS anyway I’m surprised you did not see any new items added. I expected your code always add single – and last one – item from the payload.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search