Closed1

ReactでClassをインスタンス化する際は、必ずmemo化しろ!

nerusannerusan

概要

Flow.jsを利用して、大容量のファイルをチャンクアップロードを実装しようとした時の話です。

詳しい使い方は、公式参照ですが、アップロードを押したら、アップロードし、途中でキャンセルしたらアップロードキャンセルをする機能を作ろうとしてました。

しかし、以下のようなコードでは

ts
const Component = ({file}: {file: File}) =>{
cont flow = new Flow({
  target:'/api/photo/redeem-upload-token', 
  query:{upload_token:'my_token'}
});
cont onUpload = () =>{
flow.addFile(file);

flow.on('fileAdded', function(file, event){
    console.log(file, event);
});
flow.on('fileSuccess', function(file,message){
    console.log(file,message);
});
flow.on('fileError', function(file, message){
    console.log(file, message);
});
 flow.upload();
}
const cancel = () =>[ 
  flow.cancel();  // アップロードキャンセルj
  flow.off();  // イベントキャンエル
}

return ( <>
  <button onClick={onUpload}>upload</button>
  <button onClick={onCancel}>cancel</button>
<>)
}

これでキャンセルとしたらキャンセルされると思ったのですが、されません。

理由は、レンダリングのたびに新しいインスタンスを生成しているためです。

cont flow = new Flow({
  target:'/api/photo/redeem-upload-token', 
  query:{upload_token:'my_token'}
});

キャンセルしたいインスタンスとは別のインスタンスでキャンセルをしているため、キャンセルされないです。

それを回避するには、useMemoを利用して、レンダリングのたびに新しくインスタンス生成をしないようにします。

ts
  const flow = React.useMemo(
    () =>
      new Flow({
        target:'/api/photo/redeem-upload-token', 
         query:{upload_token:'my_token'}
      }),
    []
  );

これでしっかりされます!!依存関係がある際は第二引数の指定を忘れずに!

このスクラップは2022/09/05にクローズされました