简体   繁体   中英

Strange behavior of useState() method of react hook while fetching data from axios

I am using axios library to fetch data from a json file through json-server. When I am loading and using the response object in a single component it is working perfectly. But when I am passing this response object to child component from parent component it is not loading the data. Also not receiving any errors, can someone please help me to understand the difference and what is wrong with my approach?

//Scenario-1 : working perfectly fine:

import React, { useState, useEffect } from 'react';
import Display from './Display';
import Note from './note'
import axios from 'axios';

const App = () => { 
  const [notes, setNotes] = useState([])

  const hook = () => {
      axios.get('http://localhost:3001/notes')
        .then(response => {
        setNotes(response.data)
      })
  }

  useEffect(hook, [])

  return (
    <div>     
        {notes.map(n => <Note key={n.id} note={n} />)}
    </div>
  )
}

export default App;


//Scenario-2 : Not working as expected, also no errors.
const Display = (props) => {    

    //Receiving data here, can see the values in console.
    console.log('inside display, props.notex: ', props.notex); 

    const [notes, setNotes] = useState(props.notex);

    //Blank object, why useState() method is not setting the value of "notes" from "props.notex".
    console.log('inside display, notes: ', notes); 

    const generateRows = () => {
        console.log('generateRows: ', notes)
        return (
            notes.map(n => <Note key={n.id} note={n} />)
        )
    }

    return (
        <div>            
            <ul>
                {generateRows()}
            </ul>           
        </div>
    )
}

const App = () => { 
  const [notes, setNotes] = useState([])

  const hook = () => {
      axios.get('http://localhost:3001/notes')
        .then(response => {
        setNotes(response.data)
      })
  }

  useEffect(hook, [])

   return (
    <div>                            
        <Display notex={notes} />        
    </div>
  )
}

export default App;

My guess is that useState is asynchronous, same as setState in Class components. Due to its async nature, you are not able to log anything - the log gets executed before the useState actually does anything.

If you really want to do it this way, you could initialize the value of the useState as an empty array and set up a useEffect hook, with the props.notex in your dependency array, something like this:

useEffect(() => {
  if (props.notex) setNotes(props.notex)
}, [props.notex])

And then in the return

return (
        <div>            
            <ul>
                {notes.length && generateRows()}
            </ul>           
        </div>
    )

But you could just pass the props down from the parent to child without setting the state in the child component.

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM