やりたいこと
ボタンを押下したら、変数を更新させて、更新された変数に合わせて画面を反映させる(useStateは使わない(!?))
useState使いたくなかった理由
useStateを使うと、再レンダリングされてしまう為、上位コンポーネントの再レンダリングをした場合、再レンダリングする必要がない下位コンポーネントまでレンダリングされてしまうから、使いたくなかった
処理イメージ
結果:無理
正確には、propsに渡して再レンダリングさせれば可能ではあるが、今回やりたいことではなかった為、ノーカン
やっぱりsetStateで再レンダリングさせる必要がある
失敗したソースコード
App.tsx
function App(){
const v = [];
for(let i=0; i<5; i++){
v.push("test: " + i);
}
const [testReturn, setTestReturn] = useState(v);
console.log(testReturn);
const t = testReturn;
function onClickEventHandler(){
const newItem = "add" + testReturn.length;
// setTestReturn([...testReturn,newItem]);
t.push(newItem);
console.log(t);
}
return (
<div className="App">
<div>
<button type="button" onClick={onClickEventHandler}>add</button>
{
t.map(
text =>(
<p key={text}>{text}</p>
)
)
}
</div>
</div>
);
}
}
上記だと、内部処理的にはDOMが増えていることになっているが、レイアウトに反映されていない為、失敗となる
(上記のような実装で表示できたら有難かった)
最終的なソースコード
App.tsx
function App(){
const v = [];
for(let i=0; i<5; i++){
v.push("test: " + i);
}
const [testReturn, setTestReturn] = useState(v);
console.log(testReturn);
const t = testReturn;
function onClickEventHandler(){
const newItem = "add" + testReturn.length;
setTestReturn([...testReturn,newItem]);
console.log(t);
}
return (
<div className="App">
<div>
<button type="button" onClick={onClickEventHandler}>add</button>
{
setTestReturn.map(
text =>(
<p key={text}>{text}</p>
)
)
}
</div>
</div>
);
}
}
まとめ
変数更新によるレイアウト更新をしたい場合は、useStateを使ってレンダリング更新させる必要があると思い知らされた
最後に
Reactにちょっとだけ慣れたけど、コンポーネント設計間違えたら不要なレンダリングをいっぱいするから、気を付けた方が良い
1コンポーネントの再レンダリングにかかる時間みたいなものが分かれば、ユーザー操作によりレイアウト更新時間が大体見積れると思った