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

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

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

/** フォーム。 */
const Form2: 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)
    }
  }, [])
  const [form1Value, setForm1Value] = useState<string>('ゆきだるま')
  const [form2Text, setForm2Text] = useState<Text>({value: 'ゆきだるま'})
  return (<>
    <div className="count">{'_______8_______'.slice(7-count, 15-count)}</div>
    <div className="netabare">1. は元に戻らない。(ネタバレ)</div>
    <div>1. {'useState<string>'}</div>
    <Form1 value={form1Value} />
    <button
      onClick={() => {setForm1Value('ゆきだるま')}}
    >1. の入力を初期値に戻す</button>
    <div>2. {'useState<{value: string}>'}</div>
    <Form2 text={form2Text} />
    <button
      onClick={() => {setForm2Text({value: 'ゆきだるま'})}}
    >2. の入力を初期値に戻す</button>
  </>)
}

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