memoにオブジェクトを渡す
基本的にmemoはshallow比較なのでオブジェクトは比較されないとなっていたので検証する。
import React, { useState, memo } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [cnt, setCnt] = useState(0);
const arr = [];
return (
<div className="App">
{cnt}
<button onClick={() => setCnt(cnt + 1)}>button</button>
<Test arr={[]} />
</div>
);
}
const Test = memo(({ arr }) => {
console.log("test", { arr });
return <div>test</div>;
});
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
確かにレンダリングされる。
useMemoつかったら?
やってみる。
import React, { useState, memo, useMemo } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [cnt, setCnt] = useState(0);
const arr = useMemo(() => [], []);
return (
<div className="App">
{cnt}
<button onClick={() => setCnt(cnt + 1)}>button</button>
<Test arr={arr} />
</div>
);
}
const Test = memo(({ arr }) => {
console.log("test", { arr });
return <div>test</div>;
});
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
お!!??
レンダリングされない!
なるほど、、
useMemoの更新
少しわかりにくいが、3の倍数のときのみuseMemoで再キャッシュするようにする。
理想は、その時だけmemoしたコンポーネントだけ更新されること。
import React, { useState, memo, useMemo } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [cnt, setCnt] = useState(1);
const [cnt3, setCnt3] = useState(0);
if (cnt % 3 === 0 && cnt !== cnt3) setCnt3(cnt);
const arr = useMemo(() => [], [cnt3]);
return (
<div className="App">
{cnt}
<button onClick={() => setCnt(cnt + 1)}>button</button>
<Test arr={arr} />
</div>
);
}
const Test = memo(({ arr }) => {
console.log("test", { arr });
return <div>test</div>;
});
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
おー!
想定どおり!!
Objectもやってみる
useMemoを使わない
import React, { useState, memo, useMemo } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [cnt, setCnt] = useState(1);
const obj = {};
return (
<div className="App">
{cnt}
<button onClick={() => setCnt(cnt + 1)}>button</button>
<Test arr={obj} />
</div>
);
}
const Test = memo(({ obj }) => {
console.log("test", { obj });
return <div>test</div>;
});
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
レンダリングされる。
useMemoを使う
import React, { useState, memo, useMemo } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [cnt, setCnt] = useState(1);
const obj = useMemo(() => ({ 'ttt': 1 }), []);
return (
<div className="App">
{cnt}
<button onClick={() => setCnt(cnt + 1)}>button</button>
<Test obj={obj} />
</div>
);
}
const Test = memo(({ obj }) => {
console.log("test", obj.ttt);
return <div>test</div>;
});
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
まとめ
memoはオブジェクトを比較してるのではなくて、参照を見ていることが確定したのと、
useMemoを使えば、オブジェクトもmemoの対象にできることがわかった!
これから使っていこう!!