75598


reactを用いて、ダミーのユーザ情報をjsonで返すAPIからデータをロードするコードを書いております。以下のようなものです。

[code]

    import React, { useState, useEffect } from "react";
    
    function App() {
      const [users, setUsers] = useState(null);
    
      useEffect(() => {
        fetch(`https://randomuser.me/api/?results=5&nat=us&inc=gender,name,email`)
          .then((res) => res.json())
          .then((json) => setUsers(json));
      }, []);
    
      return (
        <table border="1">
          <tr>
            <th>Name</th>
            <th>Gender</th>
            <th>Email</th>
          </tr>
          {users.results.map((result) => {
            return (
              <tr>
                <td>{result.name.first}</td>
                <td>{result.gender}</td>
                <td>{result.email}</td>
              </tr>
            );
          })}
        </table>
      );
    }
    
    export default App;
    
[/code]

このコードを実行すると`TypeError: Cannot read property 'results' of
null`というエラーが表示されてしまいます。しかし一方で`return(<table>...</table>)`内が

[code]

      return users ? (
        <h1>
          {users.results.map((result) => {
            return result.name.first;
          })}
        </h1>
      ) : (
        <p>Loading...</p>
      );
    
[/code]

のコードの後、最初のコードを実行するとテーブルが表示されます。再度ロードすると、`TypeError: Cannot read property
'results' of null`が表示されます。  
2番目のコードは再ロード後も正常に実行されます。`users.results.map()`は同じにもかかわらず、なぜこのような違いが生じるのでしょうか。またどうすればエラーが生じなくなるでしょうか。  
よろしくお願いいたします。


CC BY-SA 4.0
2021-04-30T13:08:32.527
75594
2021-04-30T21:50:01.477
2021-04-30T21:14:41.737
2808
30396
question
javascript json reactjs
APIからjsonを得た後にページをロードするとjsonが読めなくなる


> なぜこのような違いが生じるのでしょうか。

後半のコードでは `users` が `null` でないかどうか(正確には `truthy`
であるかどうか)をチェックしていますが、前半のコードではチェックしていません。

これに加えて、[初期値](https://ja.reactjs.org/docs/hooks-state.html#declaring-a-state-
variable)を `null` としている

[code]

      const [users, setUsers] = useState(null);
    
[/code]

ため、常にエラーが発生します。

> どうすればエラーが生じなくなるでしょうか。

1つめの方法は、後半のコードと同様、 `users` の `null` チェックを行うことです。

[code]

          {users ? (
            users.results.map((result) => {
              return (
                <tr>
                  <td>{result.name.first}</td>
                  <td>{result.gender}</td>
                  <td>{result.email}</td>
                </tr>
              );
            })
          ) : (
            <tr>
              <td>Loading...</td>
              <td>Loading...</td>
              <td>Loading...</td>
            </tr>
          )}
    
[/code]

2つめの方法は、初期値を適切に設定し`null`となるような状況を無くすことです。

[code]

      const [users, setUsers] = useState({ results: [] });
    
[/code]


CC BY-SA 4.0
2021-04-30T21:17:53.103
75598
2021-04-30T21:50:01.477
2021-04-30T21:50:01.477
2808
2808
75594
answer