score:0

Accepted answer

the usage of useeffect hook notifies react that component has to perform some side-effects(passed as a callback function to the hook) after it has been rendered, the default behavior of useeffect will run both after the first render and after every update, but when an empty array is passed as a dependency the side-effect will be performed only once after the component has been mounted for the first time.

in the case above useeffect(hook, []) the callback hook will be called after the component has mounted for the first time, which means the component will render with the initial state on it's first render which is an empty array ([]).

that is why when you try to access countries[1].name it errors out, because the value of countries is still an empty array on the first render.

const [ countries, setcountries ] = usestate([])

  const hook = () => {
    axios
      .get('https://restcountries.eu/rest/v2/all')
      .then(response => {
        setcountries(response.data)
      })
  }

  useeffect(hook, [])

 // can not use index expression to get the first element because
 // the value of countries is still an empty array on first render
 // it only gets populated when axios.get call is succesful inside the  
 // callback in useeffect hook after the component has mounted for the first time
 console.log(countries[1].name) 

solution check for the length of the array before trying to get the first element,

if (countries.length) {
  console.log(countries[1].name)
}

p.s.- you should be using a .catch block for handling the error when the api call fails.

score:0

there is an example solution for a type of request like this in the react document:

https://reactjs.org/docs/hooks-effect.html

the hooks provided by react are for the most part, asynchronous functions provided by react, to help manage the loading of data, presenting it to the dom, and dealing with updates. the useeffect behaves in a similar way to componenthasloaded, where the hook is triggered once the functional component has rendered, and the dom has been loaded, but it may not have been presented to the user yet. it's important to remember this when working with useeffect. usestate is another asynchronous hook, but it provides access to the state property of the hook after it has been instantiated, and won't immediately trigger a re-render of the component, unless the data is updated.

the reason you get an undefined error when you attempt to access console.log(countries[1].name) is because the array at that point is still empty.

i'll explain in code:

const mycomponent = () => {

  // initialise countries: []
  const [ countries, setcountries ] = usestate([])

  const hook = () => {
    axios
      .get('https://restcountries.eu/rest/v2/all')
      .then(response => {
        // this is allow you to see the dom change after the effect has run
        settimeout(() => setcountries(response.data), 5000);
      })
  }

  // tell react to run useeffect once the component is loaded
  useeffect(hook, [])

  // display data
  return (
    <p>countries: {countries.length}<p>
  );
};

because useeffect is an asynchronous function, it doesn't block the execution of the function and the rendering of the dom, but refreshes the dom once useeffect is completed. in this case, you are setting the country list, based on the result of the useeffect function.

the useeffect function will still trigger, you will have access to the state, and the function will re-render when the state is updated.

see codepen example:

https://codepen.io/jmitchell38488/pen/ojmxzpv

score:1

coz you can loop through the empty array, but you can't access the index which is not available yet

// so if
countries = []

// this will not throw error
{countries.map(country => (
       <li>{country.name}</li>
))}

// but this will
console.log(countries[1].name)

// if you want to check try to run this
console.log(countries.length ? countries[1].name : "not available yer");

Related Query

More Query from same tag