<div class="div0"></div>
.count {
  margin-bottom: 1em;
}
type VFC = React.VFC
const {useEffect, useMemo, useRef, useState} = React
const {render} = ReactDOM

/** テキスト入力の情報。 */
type Text = {
  value: string;
}

/** フォーム。 */
const Form: VFC<{text: Text}> = (props) => {
  const previousPropsRef = useRef<{text: Text} | undefined>(undefined)
  const [text, setText] = useState<Text>({value: ''})
  if (props.text !== previousPropsRef.current?.text) {
    setText({value: props.text.value})
  }
  previousPropsRef.current = props
  return (
    <form>
      <input
        value={text.value}
        onChange={
          ({currentTarget: {value}}) => {
            setText({value})
          }
        }
      />
    </form>
  )
}

/** フォームのあるアプリケーション。 */
const App: VFC<{}> = () => {
  // 888msごとにうごく8
  const [count, setCount] = useState<number>(0)
  useEffect(() => {
    const timerId = setInterval(() => {setCount((prev) => prev < 7 ? prev + 1 : 0)}, 888)
    return () => {
      clearInterval(timerId)
    }
  }, [])
  // 1.
  const text: Text = {value: 'ゆきだるま'}
  // 2.
  const memoizedText = useMemo<Text>(() => ({value: 'ゆきだるま'}), [])
  // 3.
  const textRef = useRef<Text>({value: 'ゆきだるま'})
  return (<>
    <div className="count">{'_______8_______'.slice(7-count, 15-count)}</div>
    <div>1. {'いつも新しいオブジェクト'}</div>
    <Form text={text} />
    <div>2. {'useMemo'}</div>
    <Form text={memoizedText} />
    <div>3. {'useRef'}</div>
    <Form text={textRef.current} />
  </>)
}

render(
  <App />,
  document.querySelector('.div0')
)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js
  3. https://unpkg.com/@types/react@17.0.37/index.d.ts
  4. https://unpkg.com/@types/react-dom@17.0.11/index.d.ts