//tips
//smart contract
リアルタイムの反映を行うためにonSnapshotを導入しようかと考えたが、export default function edit({ ninja })の引数として、getStaticPropsで処理されたものを引き受けているという事情があるので、リアルタイムに反映させるのはgetStaticPropsで再度処理を行なったものを表示させるか、edit自身で処理を行えるかを考える必要がある。
データベースのリアルタイム変化を受けてgetStaticPropsが都度実行されて、editに引き渡されるのなら従来のやり方で良いので、
await getDocs(q)
.then((snapshot)=>{
の内容を変更してみる。
await onSnapshot(q,(snapshot)=>{
これでリアルタイムの変更に対応できるか確認。
新たなエラーが発生。imageの読み込みの際に使用していた"gs://myapp-8e583.appspot.com/"+ninja[0].userid+"/image.jpg"
が利用できなくなっている。
TypeError: Cannot read property 'userid' of undefined
const gsReference = ref(
Console.logで確認するとninjaへの情報引き渡しがうまくいっていなさそう。
getStaticProps内のconsole.log(posts)を確認。
読み込みタイミングが遅くなるためか。
描画の順番を確認してみると
export default function edit({ ninja }) の中身である
abc
が先に来て、引数を渡す元であるexport const getStaticProps = async (context) => {の中身のログが後にきている。
doc.id 1
doc.id BbCfw7K8mdMepSmoobNJ
doc.id ZGnVMD4Bmxvl7NdwboXO
doc.id notes1
なぜgetStaticPropsを飛び越えてメインのコンポーネントが発動してしまうのか。この制御方法を探す必要がありそう。
その前にSSGについて再確認していたところ、ビルド時1回だけデータフェッチして、ビルドされた後にデータを変更することができないので、SSG はビルド後にデータを変更する必要がないページに使用される。
リアルタイム制御はSSGではできないのでSSRのgetServerSidePropsを使う必要がある。
今回は常にサーバーサイドレンダリングする負荷は今のところかける予定はないので、リアルタイムにカードの入れ替えを行うのは相性が悪いか。
代わりにカードの部分の編集機能と削除・アップロードの簡易化でこの部分は対応する。
それに伴いカード機能は掲示板・メモの用途とmediumなどのblog掲載のものとに分ける必要がある。
Addcontentsのものの下にedit contentsの枠も作り、editボタンを押されたら表示させるようにするか。
const handleflagchange=async()=>{
seteditFlag(!openeditflag)
}
このイベント関数をカード内ののボタンを押すと発動させるようにする。関数の引き渡しだけが少し面倒だが比較的シンプル。
<CardActions>
<Button onClick={()=>handleOrderchangeright(note.docid)}><ArrowForwardIosOutlinedIcon /></Button>
<Button onClick={()=>handleflagchange()} size="small">edit</Button>
</CardActions>
これでカード内のボタンを押すとテキストボックスが表示されるようにできた。
さらにクリックしたカードの現状の内容をテキストフィールドの中に表示して、そちらをベースに変更処理ができるようにしている。
const handleflagchange=async(id)=>{
seteditFlag(!openeditflag)
ninja.forEach(Item => {
if(Item.docid ===id){
setTitle(Item.title)
setDetails(Item.details)
setScategory(Item.category)
}
}
);
}
<TextField
onChange={(e)=>setTitle(e.target.value)}
variant="outlined"
color="secondary"
defaultValue={title}
fullWidth
required
/>
これで無事にeditボタンを押したカード情報を取得して表示させることができた。
ここから変更を加えてフォームを提出するタイミングでデータベースへのアップロード処理を加えることにする。
それはformのイベント関数であるhandleOnEditcontentsに記述していく。
こちらはhandleOnAddcontentsの内容と同じで問題ないかと思っていたらupdate処理ではなくadd処置になっていたので変更。
Updateのためにはdocidを引き継ぐ必要があったので
var flagdocid=null;
const handleflagchange=async(id)=>{
と先の箇所にdocidを格納する手順を追加。
下記を行い、更新処理を確認。
const updateRef = doc(firebaseApp,'mydata',flagdocid);