<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
This Pen doesn't use any external CSS resources.