落とし穴

クラス�?δ»£γ‚γ‚Šγ«ι–’ζ•°γ§γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’οΏ½?οΏ½ηΎ©γ™γ‚‹γ“γ¨γ‚’ζŽ¨ε₯¨γ—γΎγ™γ€‚η§»θ‘Œζ–Ήζ³•γ―こけら。

PureComponent は Component γ¨δΌΌγ¦γ„γΎγ™γŒγ€εŒγ˜ props と state γ«ε―Ύγ—γ¦γ―ε†γƒ¬γƒ³γƒ€γƒΌγ‚’γ‚Ήγ‚­γƒƒγƒ—γ—γΎγ™γ€‚γ‚―γƒ©γ‚Ήγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ―γΎγ  React γ«γ‚ˆγ£γ¦γ‚΅γƒγƒΌγƒˆγ•γ‚Œγ¦γ„γΎγ™γŒγ€ζ–°γ—γ„γ‚³γƒΌγƒ‰γ§οΏ½?δ½Ώη”¨γ―ζŽ¨ε₯¨γ•γ‚ŒγΎγ›γ‚“γ€‚

class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}

γƒͺフゑレンス

PureComponent

同じ props と state γ«ε―Ύγ—γ¦γ‚―γƒ©γ‚Ήγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?ε†γƒ¬γƒ³γƒ€γƒΌγ‚’γ‚Ήγ‚­γƒƒγƒ—γ—γŸγ„ε ΄εˆγ€Component οΏ½?δ»£γ‚γ‚Šγ« PureComponent を碙承します。

import { PureComponent } from 'react';

class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}

PureComponent は Component οΏ½?γ‚΅γƒ–γ‚―γƒ©γ‚Ήγ§γ‚γ‚Šγ€γ™γΉγ¦οΏ½? Component API γ‚’γ‚΅γƒγƒΌγƒˆγ—γ¦γ„γΎγ™γ€‚PureComponent を拑弡することは、props と state を桅く比較するカスタム�? shouldComponentUpdate パソッドを�?οΏ½ηΎ©γ™γ‚‹γ“γ¨γ¨εŒη­‰γ§γ™γ€‚

さらに例を見る


使用法

γ‚―γƒ©γ‚Ήγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?不要γͺ再レンダーをスキップする

React γ―ι€šεΈΈγ€θ¦ͺγŒε†γƒ¬γƒ³γƒ€γƒΌγ•γ‚Œγ‚‹γŸγ³γ«γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’ε†γƒ¬γƒ³γƒ€γƒΌγ—γΎγ™γ€‚ζœ€ι©εŒ–γ¨γ—γ¦γ€ζ–°γ—γ„ props γ‚„ state γŒε€γ„ props γ‚„ state γ¨εŒγ˜γ§γ‚γ‚‹ι™γ‚Šγ€θ¦ͺγŒε†γƒ¬γƒ³γƒ€γƒΌγ•γ‚Œγ¦γ‚‚ React γŒε†γƒ¬γƒ³γƒ€γƒΌγ‚’θ‘Œγ‚γͺγ„γ€γ¨γ„γ†γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’δ½œζˆγ™γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚γ‚―γƒ©γ‚Ήγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§γ―γ€PureComponent γ‚’ηΆ™ζ‰Ώγ™γ‚‹γ“γ¨γ«γ‚ˆγ‚Šγ€γ“οΏ½?ζŒ™ε‹•γ‚’ζœ‰εŠΉεŒ–γ§γγΎγ™γ€‚

class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}

React γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ―εΈΈγ«η΄”η²‹γͺγƒ¬γƒ³γƒ€γƒΌγƒ­γ‚Έγƒƒγ‚―γ‚’ζŒγ€γΉγγ§γ™γ€‚γ“γ‚Œγ―γ™γͺわけ、そ�? props、stateγ€γ‚³γƒ³γƒ†γ‚―γ‚ΉγƒˆγŒε€‰γ‚γ‚‰γͺγ„ε ΄εˆγ―γ€εΈΈγ«εŒγ˜ε‡ΊεŠ›γ‚’θΏ”γ™εΏ…θ¦γŒγ‚γ‚‹γ€γ¨γ„γ†ζ„ε‘³γ§γ™γ€‚PureComponent を使用することで、あγͺた�?γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒγ“οΏ½?θ¦δ»Άγ‚’ζΊ€γŸγ—γ¦γ„γ‚‹γ¨ React γ«δΌγˆγ‚‹γ“γ¨γŒγ§γγ€γοΏ½?γŸγ‚ React は props と state γŒε€‰γ‚γ‚‰γͺγ„ι™γ‚Šε†γƒ¬γƒ³γƒ€γƒΌγ™γ‚‹εΏ…θ¦γŒγͺγ„γ¨εˆ€ζ–­γ—γΎγ™γ€‚γŸγ γ—γ€δ½Ώη”¨γ—γ¦γ„γ‚‹γ‚³γƒ³γƒ†γ‚―γ‚ΉγƒˆγŒε€‰ζ›΄γ•γ‚ŒγŸε ΄εˆγ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ―ε†γƒ¬γƒ³γƒ€γƒΌγ•γ‚ŒγΎγ™γ€‚

δ»₯δΈ‹οΏ½?例で、name γŒε€‰ζ›΄γ•γ‚Œγ‚‹γŸγ³γ« Greeting γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒε†γƒ¬γƒ³γƒ€γƒΌγ•γ‚Œγ‚‹οΌˆname が props γ¨γ—γ¦ζΈ‘γ•γ‚Œγ¦γ„γ‚‹γŸγ‚οΌ‰γŒγ€address γŒε€‰ζ›΄γ•γ‚Œγ¦γ‚‚ε†γƒ¬γƒ³γƒ€γƒΌγ•γ‚Œγͺγ„οΌˆGreeting に props γ¨γ—γ¦ζΈ‘γ•γ‚Œγ¦γ„γͺγ„γŸγ‚οΌ‰γ“γ¨γ«ζ³¨οΏ½?してください。

import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

落とし穴

クラス�?δ»£γ‚γ‚Šγ«ι–’ζ•°γ§γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’οΏ½?οΏ½ηΎ©γ™γ‚‹γ“γ¨γ‚’ζŽ¨ε₯¨γ—γΎγ™γ€‚η§»θ‘Œζ–Ήζ³•γ―こけら。


代替手�?οΏ½

PureComponent クラス�?γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‹γ‚‰ι–’ζ•°γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγΈοΏ½?移葌

ζ–°γ—γ„γ‚³γƒΌγƒ‰γ§γ―γ€γ‚―γƒ©γ‚Ήγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?δ»£γ‚γ‚Šγ«ι–’ζ•°γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’δ½Ώη”¨γ™γ‚‹γ“γ¨γ‚’ζŽ¨ε₯¨γ—ます。δ»₯δΈ‹γ§γ―γ€ζ—’ε­˜οΏ½? PureComponent γ‚’δ½Ώη”¨γ—γŸγ‚―γƒ©γ‚Ήγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒγ‚γ‚‹ε ΄εˆγ€γ©οΏ½?γ‚ˆγ†γ«η§»θ‘Œγ™γ‚‹γ‹γ‚’θͺ¬ζ˜Žγ—γΎγ™γ€‚γ“γ‘γ‚‰γŒε…ƒοΏ½?コードです。

import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

こ�?γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’γ‚―γƒ©γ‚Ήγ‹γ‚‰ι–’ζ•°γ«η§»θ‘Œγ—γŸγ„ε ΄εˆγ―γ€memo でラップしてください。

import { memo, useState } from 'react';

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  return <h3>Hello{name && ', '}{name}!</h3>;
});

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

補袳

PureComponent とは異γͺγ‚Šγ€memo は新旧�? state γ‚’ζ―”θΌƒγ—γΎγ›γ‚“γ€‚ι–’ζ•°γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§γ―γ€εŒδΈ€οΏ½? state 倀で set ι–’ζ•°γ‚’ε‘Όγ³ε‡Ίγ—γŸε ΄εˆγ€memo がγͺγγ¦γ‚‚γƒ‡γƒ•γ‚©γƒ«γƒˆγ§ε†γƒ¬γƒ³γƒ€γƒΌγŒι˜²ζ­’γ•γ‚ŒγΎγ™γ€‚