20
6

More than 1 year has passed since last update.

React.js&Next.js超入門 第2版 サンプルコードのバグまとめ

Last updated at Posted at 2021-08-15

掌田津耶乃 React.js&Next.js超入門 第2版で学習を進めていていますが、サンプルコードでいくつかバグやミスがあるのでまとめます。

4-6 簡易メモ

React.js&Next.js超入門 第2版の簡易メモのバグ修正

参照

5-3 fetch APIでJSONデータにアクセスする

React.js&Next.js超入門 第2版の無限ループのバグ修正

参照

5-3 SWRを利用する

デフォルトのfetcherはもうない

319pから使っているuseSWRについて、最近swrがv1にアップデートされ、上記のようにデフォルトのfetcherがなくなりました。このためswrのV1.0以降インストールすると、この書籍のswr関連のコードはうまく動きません。

解決策として、

const fetcher = (...args) => fetch(...args).then(res => res.json())

export default function Home(){
  const{data}=useSWR('/data.json',fetcher)
  ...

jsonをパースするようなfetcherを自分で作り、useSWRの第2引数に指定するか、swrをインストールする際に

npm install swr@0.5.6

と古いバージョンを指定してインストールするようにしてください。

useSWR使用上のミス

これはバグではなくミスですが、useSWRの2つ目の返り値をerrとしていますが、useSWRの返り値はオブジェクトで、プロパティ名はdataとerrorで固定なので、正しくはこうです。

const { data,error}= useSWR(/data.txt,func)

どうしてもerrという変数名にしたい場合は次のようにします。

const { data,error:err}= useSWR(/data.txt,func)

なぜこうなるかについては、331pで返り値がオブジェクトのときの分割代入の説明をしているので、その説明が参考になると思います。
もしくはJavaScriptのオブジェクトの分割代入について調べると参考になると思います。

ただ、このコードではerrを使っていないので、このミスはエラーになっていないです。

5-4 プログラマブル電卓

5-4のプログラマブル電卓にもバグがあります。
343pのCalc.jsの中ほど、doFunc()関数内で

Calc.js
    const fe = eval(f.function)
    const res = fe(arr)

となっていますがこのままだと関数に配列がそのまま渡されてしまいます。次のようにスプレッド構文で配列を展開して渡さないといけません。

Calc.js
    const fe = eval(f.function)
    const res = fe(...arr)

コード改善

またこれは余談ですが、せっかく前の節でuseSWRを学んだのに、このプログラマブル電卓では使っていません

Calc.js
export default function Calc(props) {
  const [message, setMessage] = useState('')
  const [input, setInput] = useState('')
  const [data, setData] = usePersist('calc-history', [])
  const [func, setFunc] = useState({func:{}})

  const fetchFunc = (address)=> 
    fetch(address).then(res => res.json())

  useEffect(() => {
    fetchFunc('/api/func').then((r)=>{
      setFunc(r)
    })
  },[data])

...

このコードを次のようにuseSWRを使えばよりシンプルになります。

Calc.js
// fetcherを用意
const fetcher = (...args) => fetch(...args).then(res => res.json())

export default function Calc(props){
  const [message, setMessage]=useState('')
  const [input,setInput]=useState('');
  const [data,setData]=usePersist('calc-history',[])

  //書籍のコードをコメントアウト
  // const [func, setFunc] = useState({func:{}})

  // const fetchFunc = (address)=> 
  //   fetch(address).then(res => res.json())

  // useEffect(() => {
  //   fetchFunc('/api/func').then((r)=>{
  //     setFunc(r)
  //   })
  // },[data])

  //代わりのコード
  const { data:func,error }=useSWR('/api/func',fetcher) 
  // 関数のJSONデータ読み込みがエラーになった時とデータ読み込み中の時の表示
  if (error) return <div className="alert alert-primary text-center">failed to load</div>
  if (!func) return <div className="alert alert-primary text-center">loading...</div>

...

データ読み込み中は、funcundefinedになっています。この時にfuncのプロパティにアクセスしようとするなど、func関連の処理をしようとすると500 internal server errorとなってしまうので、funcundefinedの場合はfunc関連の処理をする前に、読み込み中であるという表示を返しておけばいいです

6章 Firebase

つい最近(2021/9/1)firebaseのJavaScript SDKのバージョンがアップデートされ、v8→v9になったようです。それに伴い、コードの互換性が失われています。

この書籍はv8で書かれているので、

# npm install firebase@8.9.1

とv8をインストールするようにするか、もしくは

import firebase from 'firebase/compat/app';

importするときにcompatをつけると、今まで通りv8として使えるようです。詳しくは上記記事を参照してください。

また、@sgigagaeruさんがこの本のFirebaseコードをv9で動くようにリファクタリングされています。

6-5 メッセージが送れるアドレスブック

これもバグではなく、仕様かもしれないです。

アドレスデータとメッセージを表示するinfo.jsについて、p425で

info.js
ログインユーザー側のmessageコレクション.add(to).then(ref=>{
  送信先アカウントのmessageコレクション.add(from).then(ref=>{
    送信先アカウントのドキュメント.update({flag:true}).then(ref=>{
      ...リダイレクト...
    })
  })
})

と、メッセージを追加した後、新着メッセージのフラグをupdate({flag:true})としてtrueに更新しています。しかしこれは送信先アカウントのアドレス帳のログインユーザー側のアドレス情報(具体的にはfirestoreのdb.collection('address').doc(router.query.id).collection('address').doc(auth.currentUser.email))にflagフィールドが存在していない場合、エラーになります。

簡単に言えば、お互いのデータがアドレス帳に登録されていないとこのメッセージアプリは使えないということです。

ただ、このエラーを回避しようとすると、コードが複雑なるのであえてこうしていると思われます。

このメッセージアプリのinfoページでメッセージを送る前に、addページでメッセージをやり取りするアカウントそれぞれでお互いのデータをアドレス帳に登録してから使うようにすればエラーは出ません。

以上

以上です。余裕があれば順次更新していきたいです。

20
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
6