🙆

【React】UseEffectの実行のタイミング【Cannot read propertie(reading 'map')】

2022/03/15に公開約2,000字

直面したエラー

取得したデータ(events)をリスト表示する為にmapを使ってviewに出力しようとしたら、

///子コンポーネント(DayList.js)
 function DayList(props) { 
/////(中略)/////
  let events = props.events
  
  const EventsList = events.map(function (val, index){
    console.log(`${val},${index}`); /////とりあえずデータが渡るかを確認
  });
return (
  <>
    <CalendarDayItem>
      <CalendarDayItems>
        <DayTime>
          {/* {EventsList} */} /////ここでデータを表示したい
        </DayTime>
/////(中略)/////
 }

以下の様にエラー

///ターミナル
Uncaught TypeError: Cannot read properties of null (reading 'map')
//nullのプロパティを読み取れない('map'を読み取る)

eventsがnullでmapが読み取れないとのこと

結論

さきに結論を書きたいと思います。

useEffectの実行のタイミングを考慮していなかったことに原因がありました。

そもそも親コンポーネントにてeventsを定義しており、propsを利用してそれぞれの子コンポーネントへ渡しております。

///親コンポーネント(App.js)
function App() {
 const [events, setEvents] = React.useState(null); /////初期値はnull

 React.useEffect(() => {     
   axios.get('/api/v1/events.js') /////APIからデータを取得
     .then(res => {
       setEvents(res.data)
     })
 }, []);

 return (
   <>
   (中略)
       <CalendarDay>
         <DayList events={events} />
     ・
     ・
     ・

上記の様にuseEffectを使ってAPIからeventsデータを呼び出しているのですが、
useEffectとはレンダリングされたタイミングで処理を実行するのが前提です。

どうしてmap実行時にeventsがnullとなってしまっているのかですが、
そもそもmap処理の部分はuseEffectが実行される前にmapが実行されてしまいます

なので、useStateにてeventsの初期値はnullとなっている為、
そのnullのままmapを実行しようとすると今回のエラーが出てしまいます。

問題解決

以下の様に書き換えたところエラーがなくなり、データが出力されました。

///子コンポーネント(DayList.js)
  let events = props.events
  /////四則演算子?をeventsの前に追加
  const EventsList = events?.map(function (val, index){ 
    console.log(`${val},${index}`);
  });
///ディベロッパー
{events: Array(6)}events: (6) [{…}, {…}, {…}, {…}, {…}, {…}]0
[[Prototype]]: Object
DayList.js:55 [object Object],0
DayList.js:55 [object Object],1
DayList.js:55 [object Object],2
DayList.js:55 [object Object],3
DayList.js:55 [object Object],4
DayList.js:55 [object Object],5

値が取れました!

eventsと.mapの間に三項演算子を挟むことによって、
eventsがnullだった場合に.map以降を実行しない様にできます。

それによってレンダリング前に.map以降を実行せずに、
レンダリング後useEffectが実行され、変数にデータが入った後にmapが実行されます!

Discussion

ログインするとコメントできます