yaakai.to

๐Ÿ–Š

React 19 Actions

React 19 ใงใฏใ€ใƒ‡ใƒผใ‚ฟๆ›ดๆ–ฐใจใใ‚Œใซไผดใ†ไธ€้€ฃใฎๆตใ‚Œใ‚’ใ†ใพใๆ‰ฑใ†ๆ–นๆณ•ใจใ—ใฆ Actions ใŒๅฐŽๅ…ฅใ•ใ‚Œใ‚‹ใ‚ˆใ†ใงใ™ใ€‚ ไพ‹ใˆใฐใ€ใ“ใ‚Œใพใงใƒ•ใ‚ฉใƒผใƒ ใฎ้€ไฟกไธญใฎ็Šถๆ…‹ใ‚’ๆฌกใฎใ‚ˆใ†ใซๆ‰ฑใ†ใ“ใจใŒใ‚ใ‚Šใพใ—ใŸใŒใ€ใ“ใ‚ŒใŒ React ใฎๆฉŸ่ƒฝใจใ—ใฆๆจ™ๆบ–ๅŒ–ใ•ใ‚Œใพใ™ใ€‚

const [isPending, setIsPending] = useState(false);
const submit = () => {
  setIsPending(true);
  await foo();
  setIsPending(false);
}
return (
      <form>
        <button click={submit} disable={isPending}>foo</button>
      </form>
    )

ๆ–ฐใ—ใๅฐŽๅ…ฅใ•ใ‚Œใ‚‹ Actions ใฎไธ€ใคใงใ‚ใ‚‹ useActionState ใ‚’ๅˆฉ็”จใ—ใฆๆ›ธใใจๆฌกใฎใ‚ˆใ†ใซๆ›ธใ‘ใพใ™ใ€‚

const [error, submitAction, isPending] = useActionState(
  async () => {
    const error = await foo();
    if (error) { return error; }
    return null;
  }
)
return (
      <form action={submitAction}>
        <button type="submit" disable={isPending}>foo</button>
      </form>
    )

Hook ใซๆธกใ—ใŸ้–ขๆ•ฐใฏๅฎŸ่ณช็š„ใซ submitAction ใฎๅ†…ๅฎนใซใชใฃใฆใ„ใฆใ€isPending ใฏใใฎ้–ขๆ•ฐใฎๅฎŸ่กŒ็Šถๆ…‹ใซๅˆใ‚ใ›ใฆๅ€คใŒๅค‰ๅŒ–ใ—ใพใ™ใ€‚ ใ“ใ‚Œใซใ‚ˆใฃใฆๆœ€ๅˆใฎใ‚ณใƒผใƒ‰ใจๅŒ็ญ‰ใซ isPending ใ‚’ไฝฟใฃใฆ UI ใฎ็Šถๆ…‹ใ‚’ๅค‰ๆ›ดใงใใ‚‹ใ€ใจใ„ใ†ใ“ใจใฎใ‚ˆใ†ใงใ™ใ€‚

useFormStatus

ใ“ใ‚Œใซ็ต„ใฟๅˆใ‚ใ›ใฆไฝฟใˆใ‚‹ใ‚‚ใฎใจใ—ใฆ useFormStatus ใจใ„ใ†่ฆชใฎ form ใฎๅฎŸ่กŒ็Šถๆ…‹ใ‚’ๅ–ๅพ—ใ™ใ‚‹ใ“ใจใŒๅ‡บๆฅใ‚‹ Hook ใ‚‚ใ‚ใ‚Šใพใ™ใ€ใ“ใ‚Œใฏ react-dom ใ‹ใ‚‰ๆไพ›ใ•ใ‚Œใ‚‹ใ‚‚ใฎใงใ™ใ€‚ ไพ‹ใˆใฐใƒœใ‚ฟใƒณใ‚ณใƒณใƒใƒผใƒใƒณใƒˆใ‚’ไฝœใ‚‹ใจใใซใใฎ็Šถๆ…‹ใ‚’ๅค–ใ‹ใ‚‰ Props ใจใ—ใฆๆธกใ™ใ“ใจใŒใ‚ใ‚‹ใจๆ€ใ„ใพใ™ใŒใ€ Actions ใ‚’ไฝฟใฃใŸ form ใฎไธญใงใฏใ“ใ‚Œใ‚’็ฐก็•ฅๅŒ–ใ™ใ‚‹ใ“ใจใŒๅ‡บๆฅใพใ™ใ€‚

function FooSubmit() {
  const { pending } = useFormStatus();
  <button type="submit" disable={pending}>foo</button>
}

function FooForm() {
  const [error, submitAction, isPending] = useActionState(
    async () => {
      const error = await foo();
      if (error) { return error; }
      return null;
    }
  )
  return (
        <form action={submitAction}>
          <FooSubmit />
        </form>
      )
}

ใ“ใ‚ŒใŒ useActionState ใฎไพ‹ใจๅŒใ˜ๅ‹•ไฝœใซใชใ‚‹ใ‚ˆใ†ใงใ™ใ€‚

useOptimistic

Actions ใŒๅคฑๆ•—ใ—ใŸใจใใซๅทปใๆˆปใ•ใ‚Œใ‚‹ useState ใฎใ‚ˆใ†ใชใ‚‚ใฎใงใ™ใ€‚ๆฌกใซใ‚ณใƒผใƒ‰ใง await foo() ใŒๅคฑๆ•—ใ™ใ‚‹ใจใ€ value ใŒ currentValue ใซๆˆปใ‚Šใพใ™ใ€‚

const [value, setValue] = useOptimistic('currentValue')
const [error, submitAction, isPending] = useActionState(
  async () => {
    setValue('newValue')
    const error = await foo();
    if (error) { return error; }
    return null;
  }
)>

ใƒฆใƒผใ‚ถใƒผๅใ‚’ๅค‰ๆ›ดใ—ใŸใ„ใŒใ€้‡่ค‡ใƒใ‚งใƒƒใ‚ฏใซๆ™‚้–“ใŒใ‹ใ‹ใ‚‹ใ‚ˆใ†ใชๅ ดๅˆใซใ€็ตๆžœใฎไบˆๅฎšใ‚’ๅ…ˆใซ UI ใซๅๆ˜ ใ—ใฆใŠใใ‚ˆใ†ใชๅ ดๅˆใซใใฎๅฎŸ่ฃ…ใŒๆจ™ๆบ–ๅŒ–ใงใใ‚‹ใ‚ˆใ†ใงใ™ใ€‚