useMemo ใฏใ€ใƒฌใƒณใƒ€ใƒผ้–“ใง่จˆ็ฎ—็ตๆžœใ‚’ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ™ใ‚‹ใŸใ‚ใฎ React ใƒ•ใƒƒใ‚ฏใงใ™ใ€‚

const cachedValue = useMemo(calculateValue, dependencies)

ใƒชใƒ•ใ‚กใƒฌใƒณใ‚น

useMemo(calculateValue, dependencies)

ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎใƒˆใƒƒใƒ—ใƒฌใƒ™ใƒซใง useMemo ใ‚’ๅ‘ผใณๅ‡บใ—ใฆใ€ใƒฌใƒณใƒ€ใƒผ้–“ใง่จˆ็ฎ—ใ‚’ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ—ใพใ™ใ€‚

import { useMemo } from 'react';

function TodoList({ todos, tab }) {
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
);
// ...
}

ใ•ใ‚‰ใซไพ‹ใ‚’่ฆ‹ใ‚‹

ๅผ•ๆ•ฐ

  • calculateValue: ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ—ใŸใ„ๅ€คใ‚’่จˆ็ฎ—ใ™ใ‚‹้–ขๆ•ฐใ€‚็ด”้–ขๆ•ฐใงใ€ๅผ•ๆ•ฐใ‚’ๅ–ใ‚‰ใšใ€ไปปๆ„ใฎๅž‹ใฎไฝ•ใ‚‰ใ‹ใฎๅ€คใ‚’่ฟ”ใ™ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚React ใฏๅˆๅ›žใƒฌใƒณใƒ€ใƒผไธญใซใ“ใฎ้–ขๆ•ฐใ‚’ๅ‘ผใณๅ‡บใ—ใพใ™ใ€‚ๆฌกๅ›žไปฅ้™ใฎใƒฌใƒณใƒ€ใƒผใงใฏใ€็›ดๅ‰ใฎใƒฌใƒณใƒ€ใƒผใจ dependencies ใŒๅค‰ๅŒ–ใ—ใฆใ„ใชใ‘ใ‚Œใฐใ€ๅŒใ˜ๅ€คใ‚’ๅ†ๅบฆ่ฟ”ใ—ใพใ™ใ€‚dependencies ใŒๅค‰ๅŒ–ใ—ใฆใ„ใ‚Œใฐใ€calculateValue ใ‚’ๅ‘ผใณๅ‡บใ—ใฆใใฎ็ตๆžœใ‚’่ฟ”ใ—ใ€ๅŒๆ™‚ใซใ€ๅพŒใ‹ใ‚‰ๅ†ๅˆฉ็”จใ™ใ‚‹ใŸใ‚ใซใใฎ็ตๆžœใ‚’ไฟๅญ˜ใ—ใพใ™ใ€‚

  • dependencies: calculateValue ใฎใ‚ณใƒผใƒ‰ๅ†…ใงๅ‚็…งใ•ใ‚Œใฆใ„ใ‚‹ใ™ในใฆใฎใƒชใ‚ขใ‚ฏใƒ†ใ‚ฃใƒ–ๅ€คใฎ้…ๅˆ—ใ€‚ใƒชใ‚ขใ‚ฏใƒ†ใ‚ฃใƒ–ๅ€คใซใฏใ€propsใ€stateใ€ใŠใ‚ˆใณใ‚ณใƒณใƒใƒผใƒใƒณใƒˆๆœฌไฝ“ใง็›ดๆŽฅๅฎฃ่จ€ใ•ใ‚Œใฆใ„ใ‚‹ใ™ในใฆใฎๅค‰ๆ•ฐใจ้–ขๆ•ฐใŒๅซใพใ‚Œใพใ™ใ€‚ใƒชใƒณใ‚ฟใŒ React ๅ‘ใ‘ใซ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹ๅ ดๅˆใฏใ€ใ™ในใฆใฎใƒชใ‚ขใ‚ฏใƒ†ใ‚ฃใƒ–ๅ€คใŒๆญฃใ—ใไพๅญ˜ๅ€คใจใ—ใฆๆŒ‡ๅฎšใ•ใ‚Œใฆใ„ใ‚‹ใ‹ใ‚’็ขบ่ชใ—ใพใ™ใ€‚ไพๅญ˜้…ๅˆ—ใฏใ€[dep1ใ€dep2ใ€dep3] ใฎใ‚ˆใ†ใซใ‚คใƒณใƒฉใ‚คใƒณใง่จ˜่ฟฐใ•ใ‚Œใ€้…ๅˆ—ใฎ้•ทใ•ใฏไธ€ๅฎšใงใ‚ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚ๅ„ไพๅญ˜ๅ€คใฏใ€Object.is ใ‚’็”จใ„ใฆใ€ๅ‰ๅ›žใฎๅ€คใจๆฏ”่ผƒใ•ใ‚Œใพใ™ใ€‚

่ฟ”ใ‚Šๅ€ค

ๅˆๅ›žใฎใƒฌใƒณใƒ€ใƒผใงใฏใ€ๅผ•ๆ•ฐใชใ—ใง calculateValue ใ‚’ๅ‘ผใณๅ‡บใ—ใŸ็ตๆžœใŒใ€useMemo ใฎ่ฟ”ใ‚Šๅ€คใจใชใ‚Šใพใ™ใ€‚

ๆฌกๅ›žไปฅ้™ใฎใƒฌใƒณใƒ€ใƒผใงใฏใ€ไพๅญ˜้…ๅˆ—ใŒๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ๅ ดๅˆใฏใ€ไปฅๅ‰ใฎใƒฌใƒณใƒ€ใƒผใงไฟๅญ˜ใ•ใ‚ŒใŸๅ€คใ‚’่ฟ”ใ—ใพใ™ใ€‚ๅค‰ๅŒ–ใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€calculateValue ใ‚’ๅ†ๅบฆๅ‘ผใณๅ‡บใ—ใ€ใใฎ็ตๆžœใ‚’ใใฎใพใพ่ฟ”ใ—ใพใ™ใ€‚

ๆณจๆ„็‚น

  • useMemo ใฏใƒ•ใƒƒใ‚ฏใชใฎใงใ€ใ‚ซใ‚นใ‚ฟใƒ ใƒ•ใƒƒใ‚ฏใ‹ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎใƒˆใƒƒใƒ—ใƒฌใƒ™ใƒซใงใ—ใ‹ๅ‘ผใณๅ‡บใ™ใ“ใจใŒใงใใพใ›ใ‚“ใ€‚ใƒซใƒผใƒ—ใ‚„ๆกไปถๅˆ†ๅฒใฎไธญใงๅ‘ผใณๅ‡บใ™ใ“ใจใฏใงใใพใ›ใ‚“ใ€‚ใ‚‚ใ—ใƒซใƒผใƒ—ใ‚„ๆกไปถๅˆ†ๅฒใฎไธญใงๅ‘ผใณๅ‡บใ—ใŸใ„ๅ ดๅˆใฏใ€ๆ–ฐใ—ใ„ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใซๅˆ‡ใ‚Šๅ‡บใ—ใฆใ€ใใฎไธญใซ state ใ‚’็งปๅ‹•ใ•ใ›ใฆใใ ใ•ใ„ใ€‚
  • Strict Mode ใงใฏใ€็ด”็ฒ‹ใงใชใ„้–ขๆ•ฐใ‚’่ฆ‹ใคใ‘ใ‚„ใ™ใใ™ใ‚‹ใŸใ‚ใซใ€่จˆ็ฎ—้–ขๆ•ฐ (calculateValue) ใŒ 2 ๅบฆๅ‘ผใณๅ‡บใ•ใ‚Œใพใ™ใ€‚ใ“ใ‚Œใฏใ€้–‹็™บๆ™‚ใฎใฟใฎๆŒ™ๅ‹•ใงใ€ๆœฌ็•ชใงใฏๅฝฑ้ŸฟใฏไธŽใˆใพใ›ใ‚“ใ€‚ใ‚‚ใ—ใ€่จˆ็ฎ—้–ขๆ•ฐใŒ็ด”็ฒ‹ใงใ‚ใ‚Œใฐ๏ผˆ็ด”็ฒ‹ใงใ‚ใ‚‹ในใใงใ™๏ผ‰ใ€2 ๅ›žๅ‘ผใณๅ‡บใ•ใ‚Œใฆใ‚‚ใ‚ณใƒผใƒ‰ใซๅฝฑ้Ÿฟใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚2 ๅ›žใฎๅ‘ผใณๅ‡บใ—ใฎใ†ใกใ€ไธ€ๆ–นใฎๅ‘ผใณๅ‡บใ—็ตๆžœใฏ็„ก่ฆ–ใ•ใ‚Œใพใ™ใ€‚
  • ็‰นๅˆฅใช็†็”ฑใŒใชใ„้™ใ‚Šใ€ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ•ใ‚ŒใŸๅ€คใŒ็ ดๆฃ„ใ•ใ‚Œใ‚‹ใ“ใจใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ‚ญใƒฃใƒƒใ‚ทใƒฅใŒ็ ดๆฃ„ใ•ใ‚Œใ‚‹ใ‚ฑใƒผใ‚นใฎไพ‹ใจใ—ใฆใฏใ€้–‹็™บๆ™‚ใซใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎใƒ•ใ‚กใ‚คใƒซใ‚’็ทจ้›†ใ—ใŸๅ ดๅˆใŒใ‚ใ‚Šใพใ™ใ€‚ใพใŸใ€้–‹็™บๆ™‚ใŠใ‚ˆใณๆœฌ็•ชๆ™‚ใซใ€ๅˆๅ›žใƒžใ‚ฆใƒณใƒˆไธญใซใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒใ‚ตใ‚นใƒšใƒณใƒ‰ใ™ใ‚‹ใจใ€ใ‚ญใƒฃใƒƒใ‚ทใƒฅใฏ็ ดๆฃ„ใ•ใ‚Œใพใ™ใ€‚ๅฐ†ๆฅ็š„ใซใฏใ€ใ‚ญใƒฃใƒƒใ‚ทใƒฅใŒ็ ดๆฃ„ใ•ใ‚Œใ‚‹ใ“ใจใ‚’ๅ‰ๆใจใ—ใŸๆฉŸ่ƒฝใŒ React ใซ่ฟฝๅŠ ใ•ใ‚Œใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚ไพ‹ใˆใฐใ€ๅฐ†ๆฅ็š„ใซไปฎๆƒณใƒชใ‚นใƒˆใŒ็ต„ใฟ่พผใฟใงใ‚ตใƒใƒผใƒˆใ•ใ‚ŒใŸๅ ดๅˆใ€ไปฎๆƒณใƒ†ใƒผใƒ–ใƒซใฎใƒ“ใƒฅใƒผใƒใƒผใƒˆใ‹ใ‚‰ใ‚นใ‚ฏใƒญใƒผใƒซใ‚ขใ‚ฆใƒˆใ—ใŸ้ …็›ฎใฏใ€ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ‚’็ ดๆฃ„ใ™ใ‚‹ใ‚ˆใ†ใซใชใ‚‹ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ใ“ใฎใ‚ˆใ†ใชๆŒ™ๅ‹•ใฏใ€ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นๆœ€้ฉๅŒ–ใฎใฟใ‚’็›ฎ็š„ใจใ—ใฆ useMemo ใ‚’ไฝฟใฃใฆใ„ใ‚‹ๅ ดๅˆใซใฏๅ•้กŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ใ€ไป–ใฎ็›ฎ็š„ใงๅˆฉ็”จใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€state ๅค‰ๆ•ฐ ใ‚„ ref ใ‚’ๅˆฉ็”จใ—ใŸๆ–นใŒ่‰ฏใ„ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚

่ฃœ่ถณ

ใ“ใฎใ‚ˆใ†ใช่ฟ”ใ‚Šๅ€คใฎใ‚ญใƒฃใƒƒใ‚ทใƒฅใฏใ€ใƒกใƒขๅŒ– (memoization) ใจใ—ใฆ็Ÿฅใ‚‰ใ‚ŒใฆใŠใ‚Šใ€ใใ‚ŒใŒใ“ใฎใƒ•ใƒƒใ‚ฏใŒ useMemo ใจใ„ใ†ๅๅ‰ใงใ‚ใ‚‹็†็”ฑใงใ™ใ€‚


ไฝฟ็”จๆณ•

้ซ˜ใ‚ณใ‚นใƒˆใชๅ†่จˆ็ฎ—ใ‚’้ฟใ‘ใ‚‹

่ค‡ๆ•ฐใƒฌใƒณใƒ€ใƒผใ‚’่ทจใ„ใง่จˆ็ฎ—ใ‚’ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ™ใ‚‹ใซใฏใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎใƒˆใƒƒใƒ—ใƒฌใƒ™ใƒซใง useMemo ใ‚’ๅ‘ผใณๅ‡บใ—ใ€่จˆ็ฎ—ใ‚’ใƒฉใƒƒใƒ—ใ—ใพใ™ใ€‚

import { useMemo } from 'react';

function TodoList({ todos, tab, theme }) {
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...
}

useMemo ใซใฏใ€2 ใคใฎๅผ•ๆ•ฐใ‚’ๆธกใ™ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚

  1. () => ใฎใ‚ˆใ†ใซใ€ๅผ•ๆ•ฐใ‚’ๅ–ใ‚‰ใšใ€ๆฑ‚ใ‚ใŸใ„่จˆ็ฎ—็ตๆžœใ‚’่ฟ”ใ™่จˆ็ฎ—้–ขๆ•ฐใ€‚
  2. ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆๅ†…ใซใ‚ใ‚‹ๅ€คใฎใ†ใกใ€่จˆ็ฎ—้–ขๆ•ฐๅ†…ใงไฝฟ็”จใ•ใ‚Œใฆใ„ใ‚‹ใ™ในใฆใฎๅ€คใ‚’ๅซใ‚€ใ€ไพๅญ˜้…ๅˆ—ใ€‚

ๅˆๅ›žใƒฌใƒณใƒ€ใƒผใงใฏใ€useMemo ใ‹ใ‚‰่ฟ”ใ•ใ‚Œใ‚‹ๅ€คใฏใ€่จˆ็ฎ—้–ขๆ•ฐใ‚’ๅ‘ผใณๅ‡บใ—ใŸ็ตๆžœใซใชใ‚Šใพใ™ใ€‚

ๆฌกๅ›žไปฅ้™ใฎใƒฌใƒณใƒ€ใƒผใงใฏใ€ไปŠๅ›žใฎใƒฌใƒณใƒ€ใƒผๆ™‚ใซๆธกใ—ใŸไพๅญ˜้…ๅˆ—ใจใ€ๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผๆ™‚ใซๆธกใ—ใŸไพๅญ˜้…ๅˆ—ใŒๆฏ”่ผƒใ•ใ‚Œใพใ™ใ€‚๏ผˆObject.is ใงๆฏ”่ผƒใ—ใพใ™ใ€‚๏ผ‰ไพๅญ˜ๅ€คใฎใ„ใšใ‚Œใ‚‚ๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ๅ ดๅˆใ€useMemo ใฏไปฅๅ‰ใซ่จˆ็ฎ—ใ—ใŸๅ€คใ‚’่ฟ”ใ—ใพใ™ใ€‚ๅค‰ๅŒ–ใ—ใฆใ„ใ‚‹ๅ ดๅˆใฏใ€ๅ†ๅบฆ่จˆ็ฎ—ใŒๅฎŸ่กŒใ•ใ‚Œใ€ๆ–ฐใ—ใ„ๅ€คใŒ่ฟ”ใ•ใ‚Œใพใ™ใ€‚

ใคใพใ‚Š useMemo ใฏใ€ไพๅญ˜้…ๅˆ—ใŒๅค‰ๅŒ–ใ—ใชใ„้™ใ‚Šใ€่ค‡ๆ•ฐใฎใƒฌใƒณใƒ€ใƒผใ‚’่ทจใ„ใง่จˆ็ฎ—็ตๆžœใ‚’ใ‚ญใƒฃใƒƒใ‚ทใƒฅใ—ใพใ™ใ€‚

ใ“ใ‚ŒใŒๅฝนใซ็ซ‹ใคๅ ด้ขใ‚’่ฆ‹ใฆใฟใพใ—ใ‚‡ใ†ใ€‚

React ใงใฏ้€šๅธธใ€ๅ†ใƒฌใƒณใƒ€ใƒผใŒ็™บ็”Ÿใ™ใ‚‹ใŸใณใซใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆ้–ขๆ•ฐๅ…จไฝ“ใŒๅ†ๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚ไพ‹ใˆใฐใ€ไปฅไธ‹ใฎ TodoList ใงใ€state ใŒๆ›ดๆ–ฐใ•ใ‚ŒใŸใ‚Šใ€่ฆชใ‹ใ‚‰ๆ–ฐใ—ใ„ props ใ‚’ๅ—ใ‘ๅ–ใฃใŸใ‚Šใ—ใŸๅ ดๅˆใ€filterTodos ้–ขๆ•ฐใŒๅ†ๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚

function TodoList({ todos, tab, theme }) {
const visibleTodos = filterTodos(todos, tab);
// ...
}

ใปใจใ‚“ใฉใฎ่จˆ็ฎ—ใฏ้žๅธธใซ้ซ˜้€Ÿใซๅ‡ฆ็†ใ•ใ‚Œใ‚‹ใŸใ‚ใ€ไฝ•ใ‹ๅ•้กŒใซใชใ‚‹ใ“ใจใฏ้€šๅธธใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ใ€ๅทจๅคงใช้…ๅˆ—ใ‚’ใƒ•ใ‚ฃใƒซใ‚ฟใƒชใƒณใ‚ฐใƒปๅค‰ๆ›ใ—ใฆใ„ใ‚‹ๅ ดๅˆใ‚„ใ€้ซ˜ใ‚ณใ‚นใƒˆใช่จˆ็ฎ—ใ‚’่กŒใฃใฆใ„ใ‚‹ๅ ดๅˆใซใฏใ€ใƒ‡ใƒผใ‚ฟใŒๅค‰ใ‚ใฃใฆใ„ใชใ‘ใ‚Œใฐใ“ใ‚Œใ‚‰ใฎ่จˆ็ฎ—ใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ—ใŸใใชใ‚‹ใงใ—ใ‚‡ใ†ใ€‚todos ใจ tab ใฎๅ€คใŒๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผๆ™‚ใจๅŒใ˜ๅ ดๅˆใ€ๅ…ˆใปใฉใฎใ‚ˆใ†ใซ่จˆ็ฎ—ใ‚’ useMemo ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ใ“ใจใงใ€ไปฅๅ‰ใซ่จˆ็ฎ—ใ—ใŸ visibleTodos ใ‚’ๅ†ๅˆฉ็”จใ™ใ‚‹ใ“ใจใŒใงใใ‚‹ใฎใงใ™ใ€‚

ใ“ใฎใ‚ˆใ†ใชใ‚ญใƒฃใƒƒใ‚ทใƒฅใฎใ“ใจใ‚’ใ€ใƒกใƒขๅŒ–ใจๅ‘ผใณใพใ™ใ€‚

่ฃœ่ถณ

useMemo ใฏใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นๆœ€้ฉๅŒ–ใฎใŸใ‚ใซใฎใฟๅˆฉ็”จใ™ใ‚‹ในใใงใ™ใ€‚useMemo ใ‚’ๅค–ใ™ใจใ‚ณใƒผใƒ‰ใŒๅ‹•ไฝœใ—ใชใ„ๅ ดๅˆใ€ใใฎๆ นๆœฌ็š„ใชๅ•้กŒใ‚’่ฆ‹ใคใ‘ใฆไฟฎๆญฃใ—ใฆใใ ใ•ใ„ใ€‚ใใฎไธŠใงใ€ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใ‚’ๅ‘ไธŠใ•ใ›ใ‚‹ใŸใ‚ใซ useMemo ใ‚’่ฟฝๅŠ ใ—ใฆใใ ใ•ใ„ใ€‚

ใ•ใ‚‰ใซๆทฑใ็Ÿฅใ‚‹

่จˆ็ฎ—ใ‚ณใ‚นใƒˆใŒ้ซ˜ใ„ใ‹ใฉใ†ใ‹ใ‚’่ฆ‹ๅˆ†ใ‘ใ‚‹ๆ–นๆณ•

้€šๅธธใ€ๆ•ฐๅƒใฎใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใฎไฝœๆˆใ‚„ใƒซใƒผใƒ—ใ‚’ใ—ใฆใ„ใชใ„้™ใ‚Šใ€้ซ˜ใ‚ณใ‚นใƒˆใช่จˆ็ฎ—ใซใฏใชใ‚‰ใชใ„ใงใ—ใ‚‡ใ†ใ€‚ใ‚ˆใ‚Šๆญฃ็ขบใชๅˆคๆ–ญใ‚’ใ—ใŸใ„ๅ ดๅˆใฏใ€ใ‚ณใƒณใ‚ฝใƒผใƒซใƒญใ‚ฐใ‚’่ฟฝๅŠ ใ—ใฆใ€ใ‚ณใƒผใƒ‰ใฎๅฎŸ่กŒใซใ‹ใ‹ใฃใŸๆ™‚้–“ใ‚’่จˆๆธฌใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

console.time('filter array');
const visibleTodos = filterTodos(todos, tab);
console.timeEnd('filter array');

่จˆๆธฌใ—ใฆใ„ใ‚‹ใ‚คใƒณใ‚ฟใƒฉใ‚ฏใ‚ทใƒงใƒณใ‚’ๅฎŸ่กŒใ—ใฆใฟใพใ—ใ‚‡ใ†๏ผˆไพ‹ใˆใฐใ€input ่ฆ็ด ใซๆ–‡ๅญ—ใ‚’ๅ…ฅๅŠ›ใ™ใ‚‹ใชใฉ๏ผ‰ใ€‚ใ™ใ‚‹ใจใ€ใ‚ณใƒณใ‚ฝใƒผใƒซใซใ€filter array: 0.15ms ใจใ„ใ†ใ‚ˆใ†ใชใƒญใ‚ฐใŒ่กจ็คบใ•ใ‚Œใพใ™ใ€‚ใƒญใ‚ฐใฎๆ™‚้–“ใŒๅ…จไฝ“็š„ใซใ‹ใชใ‚Š้•ทใ„๏ผˆไพ‹ใˆใฐ 1ms ไปฅไธŠ๏ผ‰ๅ ดๅˆใ€ใใฎ่จˆ็ฎ—ใ‚’ใƒกใƒขๅŒ–ใ™ใ‚‹ใ“ใจใŒๆœ‰ๅŠนใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใ€‚ๅฎŸ้จ“ใจใ—ใฆใ€่จˆ็ฎ—ใ‚’ useMemo ใงใƒฉใƒƒใƒ—ใ—ใฆใฟใฆใ€ใใฎใ‚คใƒณใ‚ฟใƒฉใ‚ฏใ‚ทใƒงใƒณใซๅฏพใ™ใ‚‹ๅˆ่จˆใฎใƒญใ‚ฐๆ™‚้–“ใŒๆธ›ๅฐ‘ใ—ใŸใ‹ใฉใ†ใ‹ใ‚’็ขบ่ชใ—ใฆใฟใฆใใ ใ•ใ„ใ€‚

console.time('filter array');
const visibleTodos = useMemo(() => {
return filterTodos(todos, tab); // Skipped if todos and tab haven't changed
}, [todos, tab]);
console.timeEnd('filter array');

useMemo ใฏใ€ๆœ€ๅˆใฎใƒฌใƒณใƒ€ใƒผใ‚’้ซ˜้€ŸๅŒ–ใ™ใ‚‹ใ“ใจใฏใงใใพใ›ใ‚“ใ€‚ๆ›ดๆ–ฐใฎๅ ดๅˆใซ้™ใฃใฆใ€ไธ่ฆใชๅ‡ฆ็†ใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

ใพใŸใ€ใปใจใ‚“ใฉใฎๅ ดๅˆใซใ€ใ‚ใชใŸใŒไฝฟใฃใฆใ„ใ‚‹ใƒžใ‚ทใƒณใฏใ€ใƒฆใƒผใ‚ถใฎใƒžใ‚ทใƒณใ‚ˆใ‚Š้ซ˜้€Ÿใซๅ‹•ไฝœใ™ใ‚‹ใงใ‚ใ‚ใ†ใ“ใจใ‚’ๅฟ˜ใ‚Œใฆใฏใ„ใ‘ใพใ›ใ‚“ใ€‚ใใฎใŸใ‚ใ€ๆ„ๅ›ณ็š„ใซๅ‡ฆ็†้€Ÿๅบฆใ‚’ไฝŽไธ‹ใ•ใ›ใฆใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใ‚’ใƒ†ใ‚นใƒˆใ™ใ‚‹ใฎใŒ่‰ฏใ„ใงใ—ใ‚‡ใ†ใ€‚ไพ‹ใˆใฐ Chrome ใงใฏใ€CPU Throttling ใ‚ชใƒ—ใ‚ทใƒงใƒณใŒๆไพ›ใ•ใ‚Œใฆใ„ใพใ™ใ€‚

ๅŠ ใˆใฆใ€้–‹็™บๆ™‚ใซ่กŒใ†ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚น่จˆๆธฌใงใฏใ€็œŸใซๆญฃ็ขบใช็ตๆžœใฏๅพ—ใ‚‰ใ‚Œใชใ„ใ“ใจใซๆณจๆ„ใ—ใฆใใ ใ•ใ„ใ€‚๏ผˆไพ‹ใˆใฐ Strict Mode ใŒใ‚ชใƒณใฎๅ ดๅˆใ€ๅ„ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฏๆœฌๆฅ 1 ๅ›žใƒฌใƒณใƒ€ใƒผใ•ใ‚Œใ‚‹ใจใ“ใ‚ใ‚’ใ€2 ๅ›žใƒฌใƒณใƒ€ใƒผใ•ใ‚Œใ‚‹ใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚๏ผ‰ๆœ€ใ‚‚ๆญฃ็ขบใซใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใ‚’่จˆๆธฌใ™ใ‚‹ใซใฏใ€ๆœฌ็•ช็”จใซใ‚ขใƒ—ใƒชใ‚’ใƒ“ใƒซใƒ‰ใ—ใ€ใƒฆใƒผใ‚ถใŒไฝฟ็”จใ™ใ‚‹ใ‚ˆใ†ใชใƒ‡ใƒใ‚คใ‚นใงใƒ†ใ‚นใƒˆใ—ใฆใใ ใ•ใ„ใ€‚

ใ•ใ‚‰ใซๆทฑใ็Ÿฅใ‚‹

ๅ…จใฆใฎๅ ดๆ‰€ใง useMemo ใ‚’ไฝฟใ†ในใใ‹?

ใ“ใฎใ‚ตใ‚คใƒˆใฎใ‚ˆใ†ใซใ€ใปใจใ‚“ใฉใฎใ‚คใƒณใ‚ฟใƒฉใ‚ฏใ‚ทใƒงใƒณใŒๅคงใพใ‹ใชใ‚‚ใฎ๏ผˆใƒšใƒผใ‚ธๅ…จไฝ“ใ‚„ใ‚ปใ‚ฏใ‚ทใƒงใƒณๅ…จไฝ“ใ‚’็ฝฎใๆ›ใˆใ‚‹ใชใฉ๏ผ‰ใงใ‚ใ‚‹ๅ ดๅˆใ€ๅคงๆŠตใฏใƒกใƒขๅŒ–ใฏไธ่ฆใงใ™ใ€‚ไธ€ๆ–นใ€ใƒ‰ใƒญใƒผใ‚คใƒณใ‚ฐใ‚จใƒ‡ใ‚ฃใ‚ฟใฎใ‚ˆใ†ใซใ€ใปใจใ‚“ใฉใฎใ‚คใƒณใ‚ฟใƒฉใ‚ฏใ‚ทใƒงใƒณใŒ็ดฐใ‹ใชใ‚‚ใฎ๏ผˆๅ›ณๅฝขใ‚’็งปๅ‹•ใ•ใ›ใ‚‹ใชใฉ๏ผ‰ใงใ‚ใ‚‹ๅ ดๅˆใ€ใƒกใƒขๅŒ–ใฏ้žๅธธใซๅฝนใซ็ซ‹ใคใงใ—ใ‚‡ใ†ใ€‚

useMemo ใ‚’ๅˆฉ็”จใ—ใŸๆœ€้ฉๅŒ–ใŒๅŠ›ใ‚’็™บๆฎใ™ใ‚‹ใฎใฏใ€ไปฅไธ‹ใฎใ‚ˆใ†ใชใ€ใปใ‚“ใฎไธ€้ƒจใฎใ‚ฑใƒผใ‚นใซ้™ใ‚‰ใ‚Œใพใ™ใ€‚

  • useMemo ใง่กŒใ†่จˆ็ฎ—ใŒ่‘—ใ—ใ้…ใใ€ใ‹ใคใ€ใใฎไพๅญ˜ๅ€คใŒใปใจใ‚“ใฉๅค‰ๅŒ–ใ—ใชใ„ๅ ดๅˆใ€‚
  • ่จˆ็ฎ—ใ—ใŸๅ€คใ‚’ใ€memo ใงใƒฉใƒƒใƒ—ใ•ใ‚ŒใŸใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎ props ใซๆธกใ™ๅ ดๅˆใ€‚ใ“ใฎๅ ดๅˆใฏใ€ๅ€คใŒๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ๅ ดๅˆใซใฏๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ—ใŸใ„ใงใ—ใ‚‡ใ†ใ€‚ใƒกใƒขๅŒ–ใ™ใ‚‹ใ“ใจใงใ€ไพๅญ˜ๅ€คใŒ็•ฐใชใ‚‹ๅ ดๅˆใซใฎใฟใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ›ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚
  • ใใฎๅ€คใŒใ€ใปใ‹ใฎใƒ•ใƒƒใ‚ฏใฎไพๅญ˜ๅ€คใจใ—ใฆๅˆฉ็”จใ•ใ‚Œใ‚‹ๅ ดๅˆใ€‚ไพ‹ใˆใฐใ€ๅˆฅใฎ useMemo ใฎ่จˆ็ฎ—็ตๆžœใŒใใฎๅ€คใซไพๅญ˜ใ—ใฆใ„ใ‚‹ๅ ดๅˆใ‚„ใ€useEffect ใŒใใฎๅ€คใซไพๅญ˜ใ—ใฆใ„ใ‚‹ๅ ดๅˆใชใฉใงใ™ใ€‚

ใ“ใ‚Œใ‚‰ใฎใ‚ฑใƒผใ‚นไปฅๅค–ใงใฏใ€่จˆ็ฎ—ใ‚’ useMemo ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ใ“ใจใซใƒกใƒชใƒƒใƒˆใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ไธ€ๆ–นใงใ€useMemo ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ใ“ใจใซใ‚ˆใ‚‹ๅคงใใชใƒ‡ใƒกใƒชใƒƒใƒˆใ‚‚ใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใใฎใŸใ‚ใ€ๅ€‹ๅˆฅใฎใ‚ฑใƒผใ‚นใ‚’่€ƒใˆใšใซใ€ๅฏ่ƒฝใช้™ใ‚Šๅ…จใฆใ‚’ใƒกใƒขๅŒ–ใ™ใ‚‹ใ‚ˆใ†ใซใ—ใฆใ„ใ‚‹ใƒใƒผใƒ ใ‚‚ใ‚ใ‚Šใพใ™ใ€‚ใ“ใฎใ‚ขใƒ—ใƒญใƒผใƒใฎใƒ‡ใƒกใƒชใƒƒใƒˆใฏใ€ใ‚ณใƒผใƒ‰ใŒ่ชญใฟใซใใใชใ‚‹ใจใ„ใ†็‚นใงใ™ใ€‚ใพใŸใ€ใ™ในใฆใฎใƒกใƒขๅŒ–ใŒๆœ‰ๅŠนใงใ‚ใ‚‹ใ‚ใ‘ใงใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚ไพ‹ใˆใฐใ€ๆฏŽๅ›žๅค‰ๅŒ–ใ™ใ‚‹ๅ€คใŒ 1 ใคๅญ˜ๅœจใ™ใ‚‹ใ ใ‘ใงใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆๅ…จไฝ“ใฎใƒกใƒขๅŒ–ใŒ็„กๆ„ๅ‘ณใซใชใฃใฆใ—ใพใ†ใ“ใจใ‚‚ใ‚ใ‚Šใพใ™ใ€‚

ๅฎŸ้š›ใซใฏใ€ๆฌกใฎๅŽŸๅ‰‡ใซๅพ“ใ†ใ“ใจใงใ€ใƒกใƒขๅŒ–ใฎๅคšใใ‚’็„กใใ™ใ“ใจใŒใงใใพใ™ใ€‚

  1. ใ‚ใ‚‹ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒไป–ใฎใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’่ฆ–่ฆš็š„ใซใƒฉใƒƒใƒ—ใ™ใ‚‹ๅ ดๅˆใฏใ€JSX ใ‚’ๅญ่ฆ็ด ใจใ—ใฆๅ—ใ‘ๅ–ใ‚‹ใ‚ˆใ†ใซใ—ใฆใใ ใ•ใ„ใ€‚ใ“ใฎใ‚ˆใ†ใซใ™ใ‚‹ใ“ใจใงใ€ใƒฉใƒƒใƒ‘ใƒผใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒ่‡ช่บซใฎ state ใ‚’ๆ›ดๆ–ฐใ—ใŸใจใใงใ‚‚ใ€ๅญ่ฆ็ด ใ‚’ๅ†ใƒฌใƒณใƒ€ใƒผใ™ใ‚‹ๅฟ…่ฆใŒใชใ„ใจ React ใŒๅˆคๆ–ญใงใใพใ™ใ€‚
  2. ใƒญใƒผใ‚ซใƒซใช state ใ‚’ๅˆฉ็”จใ—ใ€ๅฟ…่ฆไปฅไธŠใซ state ใ‚’ใƒชใƒ•ใƒˆใ‚ขใƒƒใƒ—ใ™ใ‚‹ใ“ใจใฏ้ฟใ‘ใฆใใ ใ•ใ„ใ€‚ไพ‹ใˆใฐใ€ใƒ•ใ‚ฉใƒผใƒ ใ‚„ใ€ใ€Œใ‚ขใ‚คใƒ†ใƒ ใŒใƒ›ใƒใƒผใ•ใ‚Œใฆใ„ใ‚‹ใ‹ใฉใ†ใ‹ใ€ใฎใ‚ˆใ†ใชไธ€ๆ™‚็š„ใช state ใฏใ€ใƒ„ใƒชใƒผใฎใƒˆใƒƒใƒ—ใƒฌใƒ™ใƒซใ‚„ใ‚ฐใƒญใƒผใƒใƒซใช state ใƒฉใ‚คใƒ–ใƒฉใƒชใซไฟๆŒใ—ใชใ„ใ‚ˆใ†ใซใ—ใฆใใ ใ•ใ„ใ€‚
  3. ใƒฌใƒณใƒ€ใƒผใƒญใ‚ธใƒƒใ‚ฏใ‚’็ด”็ฒ‹ใซไฟใคใ‚ˆใ†ใซใ—ใฆใใ ใ•ใ„ใ€‚ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎๅ†ใƒฌใƒณใƒ€ใƒผใซใ‚ˆใฃใฆใ€ไฝ•ใ‹ๅ•้กŒใŒ่ตทใใŸใ‚Šใ€็›ฎใซ่ฆ‹ใˆใ‚‹ๅ•้กŒใŒๅผ•ใ่ตทใ“ใ•ใ‚ŒใŸใ‚Šใ™ใ‚‹ๅ ดๅˆใ€ใใ‚Œใฏใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎใƒใ‚ฐใงใ™๏ผ ใƒกใƒขๅŒ–ใ‚’ใ™ใ‚‹ใฎใงใฏใชใใ€ใƒใ‚ฐใ‚’ไฟฎๆญฃใ—ใฆใใ ใ•ใ„ใ€‚
  4. state ใ‚’ๆ›ดๆ–ฐใ™ใ‚‹ไธ่ฆใชใ‚จใƒ•ใ‚งใ‚ฏใƒˆใ‚’้ฟใ‘ใฆใใ ใ•ใ„ใ€‚React ใ‚ขใƒ—ใƒชใฎใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นๅ•้กŒใฎใปใจใ‚“ใฉใฏใ€ใ‚จใƒ•ใ‚งใ‚ฏใƒˆๅ†…ใงใฎ้€ฃ้Ž–็š„ใช state ๆ›ดๆ–ฐใซใ‚ˆใฃใฆใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎใƒฌใƒณใƒ€ใƒผใŒไฝ•ๅบฆใ‚‚ๅผ•ใ่ตทใ“ใ•ใ‚Œใ‚‹ใŸใ‚ใซ็”Ÿใ˜ใพใ™ใ€‚
  5. ใ‚จใƒ•ใ‚งใ‚ฏใƒˆใ‹ใ‚‰ไธ่ฆใชไพๅญ˜ๅ€คใ‚’ๅ‰Š้™คใ—ใฆใใ ใ•ใ„ใ€‚ไพ‹ใˆใฐใ€ใƒกใƒขๅŒ–ใ™ใ‚‹ไปฃใ‚ใ‚Šใซใ€ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚„้–ขๆ•ฐใ‚’ใ‚จใƒ•ใ‚งใ‚ฏใƒˆใฎไธญใ‚„ๅค–ใซ็งปๅ‹•ใ•ใ›ใ‚‹ใ ใ‘ใงใ€็ฐกๅ˜ใซ่งฃๆฑบใงใใ‚‹ๅ ดๅˆใŒใ‚ใ‚Šใพใ™ใ€‚

ใใ‚Œใงใ‚‚็‰นๅฎšใฎใ‚คใƒณใ‚ฟใƒฉใ‚ฏใ‚ทใƒงใƒณใŒ้…ใ„ใจๆ„Ÿใ˜ใ‚‹ๅ ดๅˆใฏใ€React Developer Tools ใฎใƒ—ใƒญใƒ•ใ‚กใ‚คใƒฉใ‚’ๅˆฉ็”จใ—ใฆใ€ใฉใฎใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใงใฎใƒกใƒขๅŒ–ใŒๆœ€ใ‚‚ๆœ‰ๅŠนใ‹ใ‚’็ขบ่ชใ—ใ€ใใ“ใงใƒกใƒขๅŒ–ใ‚’่กŒใ„ใพใ—ใ‚‡ใ†ใ€‚ใ“ใ‚Œใ‚‰ใฎๅŽŸๅ‰‡ใ‚’ๅฎˆใ‚‹ใ“ใจใงใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎใƒ‡ใƒใƒƒใ‚ฐใ‚„็†่งฃใŒๅฎนๆ˜“ใซใชใ‚‹ใŸใ‚ใ€ๅธธใซๅŽŸๅ‰‡ใซๅพ“ใ†ใ“ใจใ‚’ใŠใ™ใ™ใ‚ใ—ใพใ™ใ€‚็งใŸใกใฏใ€้•ทๆœŸ็š„ใช่ฆ–็‚นใงใฏใ€ใ“ใ‚Œใ‚‰ใฎๅ•้กŒใ‚’ไธ€ๆฐ—ใซ่งฃๆฑบใ™ใ‚‹ใ“ใจใŒใงใใ‚‹็ดฐใ‹ใ„ใƒกใƒขๅŒ–ใ‚’่‡ชๅ‹•ๅŒ–ใ™ใ‚‹ๆ–นๆณ•ใ‚’็ ”็ฉถใ—ใฆใ„ใพใ™ใ€‚

useMemo ใจๅ€คใ‚’็›ดๆŽฅ่จˆ็ฎ—ใ™ใ‚‹ใ“ใจใฎ้•ใ„

ไพ‹ 1/2:
useMemo ใ‚’ๅˆฉ็”จใ—ใฆๅ†่จˆ็ฎ—ใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ™ใ‚‹

ใ“ใฎไพ‹ใงใฏ filterTodos ใฎๅฎŸ่ฃ…ใซใฏใ‚ใˆใฆ้…ๅปถใŒๅ…ฅใฃใฆใ„ใพใ™ใ€‚ใใฎใŸใ‚ใ€ใƒฌใƒณใƒ€ใƒผไธญใซๅ‘ผใณๅ‡บใ™ JavaScript ใฎ้–ขๆ•ฐใฎๅ‡ฆ็†ใŒ่‘—ใ—ใ้…ใ„ๅ ดๅˆใซใ€ใฉใ†ใชใ‚‹ใ‹ใ‚’็ขบ่ชใงใใพใ™ใ€‚ใ‚ฟใƒ–ใ‚’ๅˆ‡ใ‚Šๆ›ฟใˆใŸใ‚Šใ€ใƒ†ใƒผใƒžใ‚’ๅˆ‡ใ‚Šๆ›ฟใˆใฆใฟใฆใใ ใ•ใ„ใ€‚

ใ‚ฟใƒ–ใฎๅˆ‡ใ‚Šๆ›ฟใˆใŒ้…ใๆ„Ÿใ˜ใ‚‰ใ‚Œใ‚‹ใฎใฏใ€ๅˆ‡ใ‚Šๆ›ฟใˆใซใ‚ˆใฃใฆใ€้…ๅปถใŒๅ…ฅใฃใฆใ„ใ‚‹ filterTodos ้–ขๆ•ฐใ‚’ๅ†ๅฎŸ่กŒใ•ใ›ใฆใ—ใพใฃใฆใ„ใ‚‹ใ‹ใ‚‰ใงใ™ใ€‚ใ“ใฎๆŒ™ๅ‹•ใฏ่€ƒใˆใฆใฟใ‚Œใฐๅฝ“ใŸใ‚Šๅ‰ใงใ€tab ใŒๅค‰ๅŒ–ใ—ใŸใฎใชใ‚‰ใ€่จˆ็ฎ—ๅ…จไฝ“ใ‚’ๅ†ๅฎŸ่กŒใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚‹ใฏใšใงใ™ใ€‚๏ผˆใชใœ 2 ๅ›žๅฎŸ่กŒใ•ใ‚Œใ‚‹ใฎใ‹ๆฐ—ใซใชใ‚‹ๅ ดๅˆใฏใ€ใ“ใกใ‚‰ใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„๏ผ‰

ๆฌกใซใ€ใƒ†ใƒผใƒžใ‚’ๅˆ‡ใ‚Šๆ›ฟใˆใฆใฟใพใ—ใ‚‡ใ†ใ€‚useMemo ใŒใ‚ใ‚‹ใŠใ‹ใ’ใงใ€ๆ„ๅ›ณ็š„ใช้…ๅปถใŒๅ…ฅใฃใฆใ„ใ‚‹ใซใ‚‚้–ขใ‚ใ‚‰ใšใ€้ซ˜้€Ÿใซๅ‹•ไฝœใ—ใฆใ„ใพใ™๏ผ todos ใจ tab๏ผˆuseMemo ใฎไพๅญ˜้…ๅˆ—ใจใ—ใฆๆธกใ—ใฆใ„ใ‚‹๏ผ‰ใŒใ€ๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผๆ™‚ใ‹ใ‚‰ๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ใŸใ‚ใ€้…ๅปถใŒๅ…ฅใฃใฆใ„ใ‚‹ filterTodos ใฎๅ‘ผใณๅ‡บใ—ใŒใ‚นใ‚ญใƒƒใƒ—ใ•ใ‚Œใฆใ„ใพใ™ใ€‚

import { useMemo } from 'react';
import { filterTodos } from './utils.js'

export default function TodoList({ todos, theme, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab]
  );
  return (
    <div className={theme}>
      <p><b>Note: <code>filterTodos</code> is artificially slowed down!</b></p>
      <ul>
        {visibleTodos.map(todo => (
          <li key={todo.id}>
            {todo.completed ?
              <s>{todo.text}</s> :
              todo.text
            }
          </li>
        ))}
      </ul>
    </div>
  );
}


ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ™ใ‚‹

useMemo ใฏใ€ๅญใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎๅ†ใƒฌใƒณใƒ€ใƒผใฎใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใ‚’ๆœ€้ฉๅŒ–ใ™ใ‚‹้š›ใซใ‚‚ๅฝนใซ็ซ‹ใคใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚ใ“ใ‚Œใ‚’่ชฌๆ˜Žใ™ใ‚‹ใŸใ‚ใซใ€TodoList ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒใ€ๅญใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎ List ใฎ props ใจใ—ใฆใ€visibleTodos ใ‚’ๆธกใ™ใ“ใจใ‚’่€ƒใˆใพใ™ใ€‚

export default function TodoList({ todos, tab, theme }) {
// ...
return (
<div className={theme}>
<List items={visibleTodos} />
</div>
);
}

props ใงใ‚ใ‚‹ theme ใ‚’ๅค‰ๅŒ–ใ•ใ›ใ‚‹ใจไธ€็žฌใ‚ขใƒ—ใƒชใŒใƒ•ใƒชใƒผใ‚บใ—ใพใ™ใŒใ€<List /> ใ‚’ JSX ใ‹ใ‚‰ๅ‰Š้™คใ™ใ‚‹ใจใ€้ซ˜้€Ÿใซๅ‹•ไฝœใ™ใ‚‹ใ‚ˆใ†ใซใชใฃใŸใฏใšใงใ™ใ€‚ใ™ใชใ‚ใกใ€ใ“ใฎ List ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใซใฏๆœ€้ฉๅŒ–ใ™ใ‚‹ไพกๅ€คใŒใ‚ใ‚‹ใจใ„ใ†ใ“ใจใงใ™ใ€‚

้€šๅธธใ€ใ‚ใ‚‹ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ‚ŒใŸใจใใฏใ€ใใฎๅญใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚‚ๅ†ๅธฐ็š„ใซๅ…จใฆๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ‚Œใพใ™ใ€‚ใ“ใ‚ŒใŒใ€TodoList ใŒ็•ฐใชใ‚‹ theme ใฎๅ€คใงๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ‚ŒใŸใจใใ€List ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚‚ไธ€็ท’ใซๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ‚Œใ‚‹็†็”ฑใงใ™ใ€‚ใ“ใฎๅ‹•ไฝœใฏใ€ๅ†ใƒฌใƒณใƒ€ใƒผใซใใ‚Œใปใฉๅคšใใฎ่จˆ็ฎ—ใ‚ณใ‚นใƒˆใ‚’ๅฟ…่ฆใจใ—ใชใ„ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใซใฏ้ฉใ—ใฆใ„ใพใ™ใ€‚ใ—ใ‹ใ—ใ€ใ‚‚ใ—ๅ†ใƒฌใƒณใƒ€ใƒผใŒ้…ใ„ใจๅˆ†ใ‹ใฃใŸๅ ดๅˆใฏใ€List ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ memo ใงๅ›ฒใ†ใ“ใจใงใ€ไธŽใˆใ‚‰ใ‚ŒใŸ props ใŒๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผใจๅŒใ˜ใงใ‚ใ‚‹ๅ ดๅˆใซ List ใฎๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

import { memo } from 'react';

const List = memo(function List({ items }) {
// ...
});

ใ“ใฎๅค‰ๆ›ดใซใ‚ˆใฃใฆใ€props ใฎๅ…จ้ …็›ฎใŒๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผใจ็ญ‰ใ—ใ„ๅ ดๅˆใซใฏใ€List ใฎๅ†ใƒฌใƒณใƒ€ใƒผใฏใ‚นใ‚ญใƒƒใƒ—ใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚ใ“ใ‚ŒใŒใ€่จˆ็ฎ—ใฎใ‚ญใƒฃใƒƒใ‚ทใƒฅใŒ้‡่ฆใซใชใ‚‹็†็”ฑใงใ™๏ผ useMemo ใ‚’ไฝฟใ‚ใšใซ visibleTodos ใฎ่จˆ็ฎ—ใ‚’่กŒใ†ใ“ใจใ‚’ๆƒณๅƒใ—ใฆใฟใฆใใ ใ•ใ„ใ€‚

export default function TodoList({ todos, tab, theme }) {
// Every time the theme changes, this will be a different array...
const visibleTodos = filterTodos(todos, tab);
return (
<div className={theme}>
{/* ... so List's props will never be the same, and it will re-render every time */}
<List items={visibleTodos} />
</div>
);
}

ไธŠ่จ˜ใฎไพ‹ใงใฏใ€filterTodos ้–ขๆ•ฐใŒๆฏŽๅ›ž็•ฐใชใ‚‹้…ๅˆ—ใ‚’็”Ÿๆˆใ—ใพใ™ใ€‚๏ผˆใ“ใ‚Œใฏใ€{} ใจใ„ใ†ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใƒชใƒ†ใƒฉใƒซใŒใ€ๆฏŽๅ›žๆ–ฐใ—ใ„ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’็”Ÿๆˆใ™ใ‚‹ใ“ใจใจไผผใฆใ„ใพใ™ใ€‚๏ผ‰้€šๅธธใ“ใ‚ŒใŒๅ•้กŒใซใชใ‚‹ใ“ใจใฏใ‚ใ‚Šใพใ›ใ‚“ใŒใ€ไปŠๅ›žใฎๅ ดๅˆใฏใ€List ใฎ props ใŒๆฏŽๅ›žๅˆฅใฎๅ€คใซใชใฃใฆใ—ใพใ„ใพใ™ใ€‚ใใฎใŸใ‚ใ€memo ใซใ‚ˆใ‚‹ๆœ€้ฉๅŒ–ใŒๆ„ๅ‘ณใ‚’ใชใ•ใชใใชใฃใฆใ—ใพใ†ใฎใงใ™ใ€‚ใ“ใ“ใงใ€useMemo ใŒๅฝนใซ็ซ‹ใกใพใ™ใ€‚

export default function TodoList({ todos, tab, theme }) {
// Tell React to cache your calculation between re-renders...
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab] // ...so as long as these dependencies don't change...
);
return (
<div className={theme}>
{/* ...List will receive the same props and can skip re-rendering */}
<List items={visibleTodos} />
</div>
);
}

visibleTodos ใฎ่จˆ็ฎ—ใ‚’ useMemo ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ใ“ใจใงใ€่ค‡ๆ•ฐใฎๅ†ใƒฌใƒณใƒ€ใƒผใฎ้–“ใงใใฎ็ตๆžœใŒๅŒใ˜ใซใชใ‚‹ใ“ใจใ‚’ไฟ่จผใงใใพใ™๏ผˆไพๅญ˜้…ๅˆ—ใŒๅค‰ใ‚ใ‚‰ใชใ„้™ใ‚Š๏ผ‰ใ€‚้€šๅธธใ€็‰นๅˆฅใช็†็”ฑใŒใชใ‘ใ‚Œใฐใ€่จˆ็ฎ—ใ‚’ useMemo ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ๅฟ…่ฆใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ“ใฎไพ‹ใงใฏใ€memo ใงๅ›ฒใ‚ใ‚ŒใŸใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใซๅ€คใ‚’ๆธกใ—ใฆใŠใ‚Šใƒฌใƒณใƒ€ใƒผใฎใ‚นใ‚ญใƒƒใƒ—ใŒใงใใ‚‹ใจใ„ใ†ใ“ใจใŒใ€ใใฎ็‰นๅˆฅใช็†็”ฑใซใ‚ใŸใ‚Šใพใ™ใ€‚ไป–ใซใ‚‚ useMemo ใ‚’่ฟฝๅŠ ใ™ใ‚‹ๅ‹•ๆฉŸใฏใ„ใใคใ‹ใ‚ใ‚Šใ€ใ“ใฎใƒšใƒผใ‚ธใง่ฉณใ—ใ่งฃ่ชฌใ—ใฆใ„ใใพใ™ใ€‚

ใ•ใ‚‰ใซๆทฑใ็Ÿฅใ‚‹

ๅ€‹ใ€…ใฎ JSX ใƒŽใƒผใƒ‰ใ‚’ใƒกใƒขๅŒ–ใ™ใ‚‹

List ใ‚’ memo ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ไปฃใ‚ใ‚Šใซใ€<List /> JSX ใƒŽใƒผใƒ‰่‡ชไฝ“ใ‚’ useMemo ใงใƒฉใƒƒใƒ—ใ—ใฆใ‚‚ๆง‹ใ„ใพใ›ใ‚“ใ€‚

export default function TodoList({ todos, tab, theme }) {
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
const children = useMemo(() => <List items={visibleTodos} />, [visibleTodos]);
return (
<div className={theme}>
{children}
</div>
);
}

ๆŒ™ๅ‹•ใฏๅŒใ˜ใซใชใ‚Šใพใ™ใ€‚visibleTodos ใŒๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ๅ ดๅˆใฏใ€List ใฏๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ‚Œใพใ›ใ‚“ใ€‚

<List items={visibleTodos} /> ใฎใ‚ˆใ†ใช JSX ใƒŽใƒผใƒ‰ใฏใ€{ type: List, props: { items: visibleTodos } } ใฎใ‚ˆใ†ใชใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใจๅŒใ˜ใงใ™ใ€‚ใ“ใฎใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ไฝœๆˆใ™ใ‚‹ใ‚ณใ‚นใƒˆใฏ้žๅธธใซๅฐใ•ใ„ใงใ™ใŒใ€React ใฏใใฎๅ†…ๅฎนใŒๅ‰ๅ›žใฎๅ†…ๅฎนใจๅŒใ˜ใ‹ใฉใ†ใ‹ใฏๅˆ†ใ‹ใ‚Šใพใ›ใ‚“ใ€‚ใใฎใŸใ‚ใ€React ใฏใ€ใƒ‡ใƒ•ใ‚ฉใƒซใƒˆใง List ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ๅ†ใƒฌใƒณใƒ€ใƒผใ™ใ‚‹ใฎใงใ™ใ€‚

ใ—ใ‹ใ—ใ€React ใŒๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผๆ™‚ใจๅ…จใๅŒใ˜ JSX ใ‚’่ฆ‹ใคใ‘ใŸๅ ดๅˆใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎๅ†ใƒฌใƒณใƒ€ใƒผใฏ่กŒใ„ใพใ›ใ‚“ใ€‚ใ“ใ‚Œใฏใ€JSX ใƒŽใƒผใƒ‰ใŒใ‚คใƒŸใƒฅใƒผใ‚ฟใƒ–ใƒซ (immutable) ใงใ‚ใ‚‹ใŸใ‚ใงใ™ใ€‚JSX ใƒŽใƒผใƒ‰ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใฏๆ™‚้–“ใŒ็ตŒ้Žใ—ใฆใ‚‚ๅค‰ๅŒ–ใ™ใ‚‹ใ“ใจใฏใชใ„ใŸใ‚ใ€ๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ—ใฆใ—ใพใฃใฆๅ•้กŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ใ€ใ“ใ‚ŒใŒๆฉŸ่ƒฝใ™ใ‚‹ใซใฏใ€ใƒŽใƒผใƒ‰ใŒ็œŸใซๅ…จใๅŒไธ€ใฎใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใงใ‚ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใ€ใ‚ณใƒผใƒ‰ไธŠใงๅŒใ˜ใ‚ˆใ†ใซ่ฆ‹ใˆใ‚‹ใ ใ‘ใงใฏไธๅๅˆ†ใงใ™ใ€‚ใ“ใฎไพ‹ใงใฏใ€useMemo ใฎใŠใ‹ใ’ใงใ€ใƒŽใƒผใƒ‰ใŒๅ…จใๅŒใ˜ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใจใชใฃใฆใ„ใ‚‹ใฎใงใ™ใ€‚

useMemo ใ‚’ไฝฟใฃใฆใ€JSX ใƒŽใƒผใƒ‰ใ‚’ๆ‰‹ๅ‹•ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ใฎใฏไธไพฟใงใ™ใ€‚ไพ‹ใˆใฐใ€ๆกไปถไป˜ใใงใƒฉใƒƒใƒ—ใ™ใ‚‹ใ“ใจใฏใงใใพใ›ใ‚“ใ€‚ใใฎใŸใ‚ใ€้€šๅธธใฏ useMemo ใง JSX ใƒŽใƒผใƒ‰ใ‚’ใƒฉใƒƒใƒ—ใ™ใ‚‹ไปฃใ‚ใ‚Šใซใ€memo ใงใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ใงใƒฉใƒƒใƒ—ใ—ใพใ™ใ€‚

ๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ™ใ‚‹ๅ ดๅˆใจๆฏŽๅ›žๅ†ใƒฌใƒณใƒ€ใƒผใ‚’่กŒใ†ๅ ดๅˆใฎ้•ใ„

ไพ‹ 1/2:
useMemo ใจ memo ใ‚’ๅˆฉ็”จใ—ใฆๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ™ใ‚‹

ใ“ใฎไพ‹ใงใฏใ€List ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใซใฏไบบ็‚บ็š„ใช้…ๅปถใŒๅ…ฅใฃใฆใ„ใพใ™ใ€‚ใใฎใŸใ‚ใ€ใƒฌใƒณใƒ€ใƒผไธญใซๅ‘ผใณๅ‡บใ—ใฆใ„ใ‚‹ React ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒ่‘—ใ—ใ้…ใ„ๅ ดๅˆใฎๆŒ™ๅ‹•ใ‚’็ขบ่ชใงใใพใ™ใ€‚ใ‚ฟใƒ–ใ‚’ๅค‰ๆ›ดใ—ใŸใ‚Šใ€ใƒ†ใƒผใƒžใ‚’ๅˆ‡ใ‚Šๆ›ฟใˆใŸใ‚Šใ—ใฆใฟใฆใใ ใ•ใ„ใ€‚

ใ‚ฟใƒ–ใฎๅˆ‡ใ‚Šๆ›ฟใˆใŒ้…ใๆ„Ÿใ˜ใ‚‹ใฎใฏใ€้…ๅปถใŒๅ…ฅใฃใฆใ„ใ‚‹ List ใ‚’ๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ›ใฆใ—ใพใฃใฆใ„ใ‚‹ใ‹ใ‚‰ใงใ™ใ€‚ใ“ใ‚Œใฏ่€ƒใˆใฆใฟใ‚Œใฐๅฝ“็„ถใงใ€tab ใŒๅค‰ๅŒ–ใ—ใŸใฎใงใ€ใƒฆใƒผใ‚ถใฎๆ–ฐใ—ใ„้ธๆŠžใ‚’็”ป้ขใซๅๆ˜ ใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚

ๆฌกใซใ€ใƒ†ใƒผใƒžใ‚’ๅˆ‡ใ‚Šๆ›ฟใˆใฆใฟใพใ—ใ‚‡ใ†ใ€‚useMemo ใจ memo ใŒใ‚ใ‚‹ใŠใ‹ใ’ใงใ€ไบบ็‚บ็š„ใช้…ๅปถใŒใ‚ใ‚‹ใซใ‚‚้–ขใ‚ใ‚‰ใšใ€้ซ˜้€Ÿใซๅ‹•ไฝœใ—ใฆใ„ใพใ™๏ผ visibleItems ้…ๅˆ—ใŒๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผๆ™‚ใ‹ใ‚‰ๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ใŸใ‚ใ€List ใฏๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ—ใฆใ„ใพใ™ใ€‚visibleItems ้…ๅˆ—ใŒๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ใฎใฏใ€todos ใจ tab๏ผˆuseMemo ใฎไพๅญ˜้…ๅˆ—ใจใ—ใฆๆธกใ—ใฆใ„ใ‚‹๏ผ‰ใŒใ€ๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผๆ™‚ใ‹ใ‚‰ๅค‰ๅŒ–ใ—ใฆใ„ใชใ„ใ‹ใ‚‰ใงใ™ใ€‚

import { useMemo } from 'react';
import List from './List.js';
import { filterTodos } from './utils.js'

export default function TodoList({ todos, theme, tab }) {
  const visibleTodos = useMemo(
    () => filterTodos(todos, tab),
    [todos, tab]
  );
  return (
    <div className={theme}>
      <p><b>Note: <code>List</code> is artificially slowed down!</b></p>
      <List items={visibleTodos} />
    </div>
  );
}


ไป–ใฎใƒ•ใƒƒใ‚ฏใซๆธกใ™ไพๅญ˜ๅ€คใ‚’ใƒกใƒขๅŒ–ใ™ใ‚‹

ใ‚ใ‚‹่จˆ็ฎ—ใŒใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎๆœฌไฝ“ใง็›ดๆŽฅไฝœๆˆใ•ใ‚ŒใŸใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใซไพๅญ˜ใ—ใฆใ„ใ‚‹ใจใ—ใพใ—ใ‚‡ใ†ใ€‚

function Dropdown({ allItems, text }) {
const searchOptions = { matchMode: 'whole-word', text };

const visibleItems = useMemo(() => {
return searchItems(allItems, searchOptions);
}, [allItems, searchOptions]); // ๐Ÿšฉ Caution: Dependency on an object created in the component body
// ...

ใ“ใฎใ‚ˆใ†ใชใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ไพๅญ˜ๅ€คใจใ—ใฆไฝฟใ†ใจใƒกใƒขๅŒ–ใฎๆ„ๅ‘ณใŒใชใใชใฃใฆใ—ใพใ„ใพใ™ใ€‚ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ‚ŒใŸใจใใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใฎๆœฌไฝ“ใซๅซใพใ‚Œใ‚‹ใ‚ณใƒผใƒ‰ใฏใ™ในใฆๅ†ๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚searchOptions ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ไฝœๆˆใ™ใ‚‹ใ‚ณใƒผใƒ‰ใ‚‚ใ€ๆฏŽๅ›žๅ†ๅฎŸ่กŒใ•ใ‚Œใพใ™ใ€‚searchOptions ใฏ useMemo ใฎไพๅญ˜ๅ€คใงใ‚ใ‚Šใ€ๆฏŽๅ›ž็•ฐใชใ‚‹ๅ€คใจใชใ‚‹ใŸใ‚ใ€ไพๅญ˜ๅ€คใŒๅค‰ๅŒ–ใ—ใŸใจๅˆคๆ–ญใ•ใ‚Œใ€searchItems ใŒๆฏŽๅ›žๅ†่จˆ็ฎ—ใ•ใ‚Œใพใ™ใ€‚

ใ“ใ‚Œใ‚’ไฟฎๆญฃใ™ใ‚‹ใซใฏใ€searchOptions ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ไพๅญ˜้…ๅˆ—ใซๆธกใ™ๅ‰ใซใ€searchOptions ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆ่‡ชไฝ“ใ‚’ใƒกใƒขๅŒ–ใ—ใพใ—ใ‚‡ใ†ใ€‚

function Dropdown({ allItems, text }) {
const searchOptions = useMemo(() => {
return { matchMode: 'whole-word', text };
}, [text]); // โœ… Only changes when text changes

const visibleItems = useMemo(() => {
return searchItems(allItems, searchOptions);
}, [allItems, searchOptions]); // โœ… Only changes when allItems or searchOptions changes
// ...

ไธŠ่จ˜ใฎไพ‹ใงใฏใ€text ใŒๅค‰ๅŒ–ใ—ใชใ‘ใ‚Œใฐใ€searchOptions ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚‚ๅค‰ๅŒ–ใ—ใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ใ€ใ•ใ‚‰ใซ่‰ฏใ„ไฟฎๆญฃๆ–นๆณ•ใฏใ€searchOptions ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใฎๅฎฃ่จ€ใ‚’ useMemo ใฎ่จˆ็ฎ—้–ขๆ•ฐใฎไธญใซ็งปๅ‹•ใ™ใ‚‹ใ“ใจใงใ™ใ€‚

function Dropdown({ allItems, text }) {
const visibleItems = useMemo(() => {
const searchOptions = { matchMode: 'whole-word', text };
return searchItems(allItems, searchOptions);
}, [allItems, text]); // โœ… Only changes when allItems or text changes
// ...

ใ“ใ‚Œใงใ€่จˆ็ฎ—ใŒ็›ดๆŽฅ text ใซไพๅญ˜ใ™ใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ—ใŸใ€‚๏ผˆtext ใฏๆ–‡ๅญ—ๅˆ—ใชใฎใงใ€Œๆ„ๅ›ณใ›ใšใ€ๅค‰ๅŒ–ใ—ใฆใ—ใพใ†ใ“ใจใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚๏ผ‰


้–ขๆ•ฐใ‚’ใƒกใƒขๅŒ–ใ™ใ‚‹

Form ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒ memo ใงใƒฉใƒƒใƒ—ใ•ใ‚Œใฆใ„ใ‚‹ใจใ—ใพใ™ใ€‚้–ขๆ•ฐใ‚’ props ใจใ—ใฆๆธกใ—ใฆใฟใพใ—ใ‚‡ใ†ใ€‚

export default function ProductPage({ productId, referrer }) {
function handleSubmit(orderDetails) {
post('/product/' + productId + '/buy', {
referrer,
orderDetails
});
}

return <Form onSubmit={handleSubmit} />;
}

{} ใŒ็•ฐใชใ‚‹ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’็”Ÿๆˆใ™ใ‚‹ใฎใจๅŒๆง˜ใซใ€function() {} ใฎใ‚ˆใ†ใช้–ขๆ•ฐๅฎฃ่จ€ใ‚„ใ€() => {} ใฎใ‚ˆใ†ใช้–ขๆ•ฐๅผใ‚‚ใพใŸใ€ใƒฌใƒณใƒ€ใƒผใ”ใจใซ็•ฐใชใ‚‹้–ขๆ•ฐใ‚’็”Ÿๆˆใ—ใพใ™ใ€‚ๆ–ฐใ—ใ„้–ขๆ•ฐใŒ็”Ÿๆˆใ•ใ‚Œใ‚‹ใ“ใจ่‡ชไฝ“ใฏๅ•้กŒใงใฏใชใใ€้ฟใ‘ใ‚‹ในใใ“ใจใงใ‚‚ใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ใ€Form ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒใƒกใƒขๅŒ–ใ•ใ‚Œใฆใ„ใ‚‹็Šถๆณใงใฏใ€Form ใฎ props ใซๆธกใ™ๅ€คใŒๅค‰ใ‚ใฃใฆใ„ใชใ„ๅ ดๅˆใฏ Form ใฎๅ†ใƒฌใƒณใƒ€ใƒผใ‚’ใ‚นใ‚ญใƒƒใƒ—ใ—ใŸใ„ใจ่€ƒใˆใ‚‹ใงใ—ใ‚‡ใ†ใ€‚ๆฏŽๅ›ž็•ฐใชใ‚‹ๅ€คใŒ props ใซใ‚ใ‚‹ใจใ€ใƒกใƒขๅŒ–ใฏ็„กๆ„ๅ‘ณใซใชใฃใฆใ—ใพใ„ใพใ™ใ€‚

useMemo ใง้–ขๆ•ฐใ‚’ใƒกใƒขๅŒ–ใ™ใ‚‹ๅ ดๅˆใฏใ€่จˆ็ฎ—้–ขๆ•ฐใŒใ•ใ‚‰ใซๅˆฅใฎ้–ขๆ•ฐใ‚’่ฟ”ใ™ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚

export default function Page({ productId, referrer }) {
const handleSubmit = useMemo(() => {
return (orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails
});
};
}, [productId, referrer]);

return <Form onSubmit={handleSubmit} />;
}

ใชใ‚“ใ ใ‹ไธๆฐๅฅฝใงใ™ใญ๏ผ ้–ขๆ•ฐใฎใƒกใƒขๅŒ–ใฏใ‚ˆใใ‚ใ‚‹ใ“ใจใชใฎใงใ€ใใ‚Œๅฐ‚็”จใฎ็ต„ใฟ่พผใฟใƒ•ใƒƒใ‚ฏใŒๆไพ›ใ•ใ‚Œใฆใ„ใพใ™ใ€‚ไฝ™่จˆใช้–ขๆ•ฐใฎๅ…ฅใ‚Œๅญใ‚’้ฟใ‘ใ‚‹ใซใฏใ€useMemo ใฎไปฃใ‚ใ‚Šใซ useCallback ใง้–ขๆ•ฐใ‚’ใƒฉใƒƒใƒ—ใ—ใพใ—ใ‚‡ใ†ใ€‚

export default function Page({ productId, referrer }) {
const handleSubmit = useCallback((orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails
});
}, [productId, referrer]);

return <Form onSubmit={handleSubmit} />;
}

ไธŠ่จ˜ใฎ 2 ใคใฎไพ‹ใฏๅฎŒๅ…จใซ็ญ‰ไพกใงใ™ใ€‚useCallback ใฎใƒกใƒชใƒƒใƒˆใฏใ€ไฝ™่จˆใช้–ขๆ•ฐใฎๅ…ฅใ‚ŒๅญใŒไธ่ฆใซใชใ‚‹ใ“ใจใ ใ‘ใงใ™ใ€‚ใใ‚Œไปฅๅค–ใฎ้•ใ„ใฏไฝ•ใ‚‚ใ‚ใ‚Šใพใ›ใ‚“ใ€‚useCallback ใซใคใ„ใฆใฎ่ฉณ็ดฐใฏใ€ใ“ใกใ‚‰ใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚


ใƒˆใƒฉใƒ–ใƒซใ‚ทใƒฅใƒผใƒ†ใ‚ฃใƒณใ‚ฐ

ๅ†ใƒฌใƒณใƒ€ใƒผใฎใŸใณใซ่จˆ็ฎ—ใŒ 2 ๅ›žๅฎŸ่กŒใ•ใ‚Œใ‚‹

Strict Mode ใงใฏใ€ๆœฌๆฅ 1 ๅ›žใ ใ‘้–ขๆ•ฐใŒๅ‘ผใณๅ‡บใ•ใ‚Œใ‚‹ใจใ“ใ‚ใงใ€2 ๅ›žๅ‘ผใณๅ‡บใ•ใ‚Œใ‚‹ใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚

function TodoList({ todos, tab }) {
// This component function will run twice for every render.

const visibleTodos = useMemo(() => {
// This calculation will run twice if any of the dependencies change.
return filterTodos(todos, tab);
}, [todos, tab]);

// ...

ใ“ใ‚Œใฏๆƒณๅฎš้€šใ‚ŠใฎๆŒ™ๅ‹•ใงใ‚ใ‚Šใ€ใ“ใ‚Œใงใ‚ณใƒผใƒ‰ใŒๅฃŠใ‚Œใ‚‹ใ“ใจใŒใ‚ใฃใฆใฏใ„ใ‘ใพใ›ใ‚“ใ€‚

ใ“ใ‚Œใฏ้–‹็™บๆ™‚ใฎใฟใฎๆŒ™ๅ‹•ใงใ€้–‹็™บ่€…ใŒใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’็ด”็ฒ‹ใซไฟใคใŸใ‚ใซๅฝน็ซ‹ใกใพใ™ใ€‚ๅ‘ผใณๅ‡บใ—็ตๆžœใฎใ†ใกใฎ 1 ใคใŒๆŽก็”จใ•ใ‚Œใ€ใ‚‚ใ† 1 ใคใฏ็„ก่ฆ–ใ•ใ‚Œใพใ™ใ€‚ใ‚ใชใŸใŒๅฎŸ่ฃ…ใ—ใŸใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใจ่จˆ็ฎ—้–ขๆ•ฐใŒ็ด”็ฒ‹ใงใ‚ใ‚Œใฐใ€ใ“ใฎๆŒ™ๅ‹•ใŒใƒญใ‚ธใƒƒใ‚ฏใซๅฝฑ้Ÿฟใ‚’ไธŽใˆใ‚‹ใ“ใจใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใ—ใ‹ใ—ใ€ใ‚‚ใ—ๆ„ๅ›ณใ›ใš็ด”็ฒ‹ใงใฏใชใ„้–ขๆ•ฐใซใชใฃใฆใ„ใŸๅ ดๅˆใฏใ€ใ“ใฎๆŒ™ๅ‹•ใซใ‚ˆใฃใฆ้–“้•ใ„ใซๆฐ—ใฅใใ€ไฟฎๆญฃใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

ใŸใจใˆใฐใ€ไปฅไธ‹ใฎ่จˆ็ฎ—้–ขๆ•ฐใฏใ€props ใจใ—ใฆๅ—ใ‘ๅ–ใฃใŸ้…ๅˆ—ใฎๆ›ธใๆ›ใˆ๏ผˆใƒŸใƒฅใƒผใƒ†ใƒผใ‚ทใƒงใƒณ๏ผ‰ใ‚’ใ—ใฆใ—ใพใฃใฆใŠใ‚Šใ€็ด”็ฒ‹ใงใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚

const visibleTodos = useMemo(() => {
// ๐Ÿšฉ Mistake: mutating a prop
todos.push({ id: 'last', text: 'Go for a walk!' });
const filtered = filterTodos(todos, tab);
return filtered;
}, [todos, tab]);

ใ—ใ‹ใ—ใ€ใ“ใฎ้–ขๆ•ฐใฏ 2 ๅบฆๅ‘ผใณๅ‡บใ•ใ‚Œใ‚‹ใŸใ‚ใ€todo ใŒ 2 ๅ›ž่ฟฝๅŠ ใ•ใ‚ŒใŸใ“ใจใซๆฐ—ใฅใใฏใšใงใ™ใ€‚่จˆ็ฎ—้–ขๆ•ฐใฏใ€ๆ—ขๅญ˜ใฎใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ๅค‰ๆ›ดใ—ใฆใฏใ„ใ‘ใพใ›ใ‚“ใŒใ€่จˆ็ฎ—ไธญใซไฝœๆˆใ—ใŸๆ–ฐใ—ใ„ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ๅค‰ๆ›ดใ™ใ‚‹ใ“ใจใฏๅ•้กŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚ใŸใจใˆใฐใ€filterTodos ้–ขๆ•ฐใŒๅธธใซ็•ฐใชใ‚‹้…ๅˆ—ใ‚’่ฟ”ใ™ๅ ดๅˆใฏใ€ใใฎ้…ๅˆ—ใ‚’ๅค‰ๆ›ดใ—ใฆใ‚‚ๅ•้กŒใ‚ใ‚Šใพใ›ใ‚“ใ€‚

const visibleTodos = useMemo(() => {
const filtered = filterTodos(todos, tab);
// โœ… Correct: mutating an object you created during the calculation
filtered.push({ id: 'last', text: 'Go for a walk!' });
return filtered;
}, [todos, tab]);

็ด”้–ขๆ•ฐใซใคใ„ใฆ่ฉณใ—ใ็Ÿฅใ‚‹ใซใฏใ€ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’็ด”็ฒ‹ใซไฟใคใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚

ใพใŸใ€ใƒŸใƒฅใƒผใƒ†ใƒผใ‚ทใƒงใƒณใชใ—ใงใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใ‚’ๆ›ดๆ–ฐใ™ใ‚‹ๆ–นๆณ•ใซใคใ„ใฆใฏใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใฎๆ›ดๆ–ฐใ‚’ใ€ใƒŸใƒฅใƒผใƒ†ใƒผใ‚ทใƒงใƒณใชใ—ใง้…ๅˆ—ใ‚’ๆ›ดๆ–ฐใ™ใ‚‹ๆ–นๆณ•ใซใคใ„ใฆใฏ้…ๅˆ—ใฎๆ›ดๆ–ฐใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚


useMemo ใฎ่ฟ”ใ‚Šๅ€คใŒใ€ใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใงใฏใชใ undefined ใซใชใฃใฆใ—ใพใ†

ไปฅไธ‹ใฎใ‚ณใƒผใƒ‰ใฏใ†ใพใๅ‹•ไฝœใ—ใพใ›ใ‚“ใ€‚

// ๐Ÿ”ด You can't return an object from an arrow function with () => {
const searchOptions = useMemo(() => {
matchMode: 'whole-word',
text: text
}, [text]);

JavaScript ใงใฏใ€() => { ใจใ„ใ†ใ‚ณใƒผใƒ‰ใงใ‚ขใƒญใƒผ้–ขๆ•ฐใฎๆœฌไฝ“ใ‚’้–‹ๅง‹ใ™ใ‚‹ใŸใ‚ใ€{ ใฎๆณขๆ‹ฌๅผงใฏใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใฎไธ€้ƒจใซใฏใชใ‚Šใพใ›ใ‚“ใ€‚ใ—ใŸใŒใฃใฆใ‚ชใƒ–ใ‚ธใ‚งใ‚ฏใƒˆใฏ่ฟ”ใ•ใ‚Œใšใ€ใƒŸใ‚นใซใคใชใŒใ‚Šใพใ™ใ€‚({ ใ‚„ }) ใฎใ‚ˆใ†ใซไธธๆ‹ฌๅผงใ‚’่ฟฝๅŠ ใ™ใ‚‹ใ“ใจใงไฟฎๆญฃใงใใพใ™ใ€‚

// This works, but is easy for someone to break again
const searchOptions = useMemo(() => ({
matchMode: 'whole-word',
text: text
}), [text]);

ใ—ใ‹ใ—ใ€ใ“ใ‚Œใงใ‚‚ใพใ ๆททไนฑใ—ใ‚„ใ™ใใ€่ชฐใ‹ใŒไธธๆ‹ฌๅผงใ‚’ๅ‰Š้™คใ—ใฆใ—ใพใ†ใจ็ฐกๅ˜ใซๅฃŠใ‚Œใฆใ—ใพใ„ใพใ™ใ€‚

ใ“ใฎใƒŸใ‚นใ‚’้ฟใ‘ใ‚‹ใŸใ‚ใซใ€ๆ˜Ž็คบ็š„ใซ return ๆ–‡ใ‚’ๆ›ธใใพใ—ใ‚‡ใ†ใ€‚

// โœ… This works and is explicit
const searchOptions = useMemo(() => {
return {
matchMode: 'whole-word',
text: text
};
}, [text]);

ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒใƒฌใƒณใƒ€ใƒผใ•ใ‚Œใ‚‹ใŸใณใซ useMemo ๅ†…ใฎ้–ขๆ•ฐใŒๅ†ๅฎŸ่กŒใ•ใ‚Œใ‚‹

็ฌฌ 2 ๅผ•ๆ•ฐใซไพๅญ˜้…ๅˆ—ใ‚’ๆŒ‡ๅฎšใ—ใฆใ„ใ‚‹ใ‹็ขบ่ชใ—ใฆใใ ใ•ใ„๏ผ

ไพๅญ˜้…ๅˆ—ใ‚’ๅฟ˜ใ‚Œใ‚‹ใจใ€useMemo ใฏๆฏŽๅ›ž่จˆ็ฎ—ใ‚’ๅ†ๅฎŸ่กŒใ—ใฆใ—ใพใ„ใพใ™ใ€‚

function TodoList({ todos, tab }) {
// ๐Ÿ”ด Recalculates every time: no dependency array
const visibleTodos = useMemo(() => filterTodos(todos, tab));
// ...

็ฌฌ 2 ๅผ•ๆ•ฐใซไพๅญ˜้…ๅˆ—ใ‚’ๆธกใ—ใŸไฟฎๆญฃ็‰ˆใฏไปฅไธ‹ใฎ้€šใ‚Šใงใ™ใ€‚

function TodoList({ todos, tab }) {
// โœ… Does not recalculate unnecessarily
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...

ใ“ใ‚Œใง่งฃๆฑบใ—ใชใ„ๅ ดๅˆใฏใ€ๅฐ‘ใชใใจใ‚‚ 1 ใคใฎไพๅญ˜ๅ€คใŒๅ‰ๅ›žใฎใƒฌใƒณใƒ€ใƒผใจ็•ฐใชใฃใฆใ„ใ‚‹ใ“ใจใŒๅ•้กŒใงใ™ใ€‚ๆ‰‹ๅ‹•ใงไพๅญ˜ๅ€คใ‚’ใ‚ณใƒณใ‚ฝใƒผใƒซใซๅ‡บๅŠ›ใ—ใฆใ€ใƒ‡ใƒใƒƒใ‚ฐใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
console.log([todos, tab]);

ใ‚ณใƒณใ‚ฝใƒผใƒซไธŠใงใ€ๅˆฅใ€…ใฎๅ†ใƒฌใƒณใƒ€ใƒผใซใ‚ˆใฃใฆ่กจ็คบใ•ใ‚ŒใŸ 2 ใคใฎ้…ๅˆ—ใ‚’้ธใณใพใ™ใ€‚ใใ‚Œใžใ‚Œใซใคใ„ใฆใ€้…ๅˆ—ใ‚’ๅณใ‚ฏใƒชใƒƒใ‚ฏใ—ใ€โ€œStore as a global variable๏ผˆใ‚ฐใƒญใƒผใƒใƒซๅค‰ๆ•ฐใจใ—ใฆไฟๅญ˜๏ผ‰โ€ ใ‚’้ธๆŠžใ™ใ‚‹ใ“ใจใงใ€้…ๅˆ—ใ‚’ไฟๅญ˜ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚1 ๅ›ž็›ฎใซไฟๅญ˜ใ—ใŸ้…ๅˆ—ใŒ temp1ใ€2 ๅ›ž็›ฎใซไฟๅญ˜ใ—ใŸ้…ๅˆ—ใŒ temp2 ใจใ—ใฆไฟๅญ˜ใ•ใ‚ŒใŸใจใ™ใ‚‹ใจใ€ใƒ–ใƒฉใ‚ฆใ‚ถใฎใ‚ณใƒณใ‚ฝใƒผใƒซใ‚’ไฝฟ็”จใ—ใฆใ€ไธกๆ–นใฎ้…ๅˆ—ใฎๅ„ไพๅญ˜ๅ€คใŒๅŒใ˜ใ‹ใฉใ†ใ‹ใ‚’็ขบ่ชใงใใพใ™ใ€‚

Object.is(temp1[0], temp2[0]); // Is the first dependency the same between the arrays?
Object.is(temp1[1], temp2[1]); // Is the second dependency the same between the arrays?
Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...

ใƒกใƒขๅŒ–ใ‚’ๅฆจใ’ใฆใ„ใ‚‹ไพๅญ˜ๅ€คใ‚’่ฆ‹ใคใ‘ใŸใ‚‰ใ€ใใฎไพๅญ˜ๅ€คใ‚’ๅ‰Š้™คใ™ใ‚‹ๆ–นๆณ•ใ‚’ๆŽขใ™ใ‹ใ€ใใฎไพๅญ˜ๅ€คใ‚‚ใƒกใƒขๅŒ–ใ—ใพใ—ใ‚‡ใ†ใ€‚


ใƒซใƒผใƒ—ๅ†…ใฎใƒชใ‚นใƒˆใฎๅ„้ …็›ฎใซใคใ„ใฆ useMemo ใ‚’ๅ‘ผใณๅ‡บใ—ใŸใ„ใŒใ€็ฆๆญขใ•ใ‚Œใฆใ„ใ‚‹

Chart ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒ memo ใงใƒฉใƒƒใƒ—ใ•ใ‚Œใฆใ„ใ‚‹ใจใ—ใพใ™ใ€‚ReportList ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใŒๅ†ใƒฌใƒณใƒ€ใƒผใ•ใ‚ŒใŸๅ ดๅˆใงใ‚‚ใ€ใƒชใ‚นใƒˆๅ†…ใฎๅ„ Chart ใฎๅ†ใƒฌใƒณใƒ€ใƒผใฏใ‚นใ‚ญใƒƒใƒ—ใ—ใŸใ„ใงใ™ใ€‚ใจใ“ใ‚ใŒใ€ไปฅไธ‹ใฎใ‚ˆใ†ใซใƒซใƒผใƒ—ๅ†…ใง useMemo ใ‚’ๅ‘ผใณๅ‡บใ™ใ“ใจใฏใงใใพใ›ใ‚“ใ€‚

function ReportList({ items }) {
return (
<article>
{items.map(item => {
// ๐Ÿ”ด You can't call useMemo in a loop like this:
const data = useMemo(() => calculateReport(item), [item]);
return (
<figure key={item.id}>
<Chart data={data} />
</figure>
);
})}
</article>
);
}

ใใฎๅ ดๅˆใฏใ€ๅ„ใ‚ขใ‚คใƒ†ใƒ ใ‚’ใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใซๅˆ‡ใ‚Šๅ‡บใ—ใ€ใ‚ขใ‚คใƒ†ใƒ ใ”ใจใซใƒ‡ใƒผใ‚ฟใ‚’ใƒกใƒขๅŒ–ใ—ใพใ™ใ€‚

function ReportList({ items }) {
return (
<article>
{items.map(item =>
<Report key={item.id} item={item} />
)}
</article>
);
}

function Report({ item }) {
// โœ… Call useMemo at the top level:
const data = useMemo(() => calculateReport(item), [item]);
return (
<figure>
<Chart data={data} />
</figure>
);
}

ใ‚ใ‚‹ใ„ใฏใ€useMemo ใ‚’ๅ‰Š้™คใ—ใ€Report ่‡ชไฝ“ใ‚’ memo ใงใƒฉใƒƒใƒ—ใ™ใ‚‹ใ“ใจใงใ‚‚่งฃๆฑบใงใใพใ™ใ€‚item ใŒๅค‰ๅŒ–ใ—ใชใ„ๅ ดๅˆใฏใ€Report ใฎๅ†ใƒฌใƒณใƒ€ใƒผใฏใ‚นใ‚ญใƒƒใƒ—ใ•ใ‚Œใ€Chart ใฎๅ†ใƒฌใƒณใƒ€ใƒผใ‚‚ใ‚นใ‚ญใƒƒใƒ—ใ•ใ‚Œใพใ™ใ€‚

function ReportList({ items }) {
// ...
}

const Report = memo(function Report({ item }) {
const data = calculateReport(item);
return (
<figure>
<Chart data={data} />
</figure>
);
});