ホームページ > ウェブフロントエンド > jsチュートリアル > React の新しいフックを理解する

React の新しいフックを理解する

DDD
リリース: 2025-01-07 20:36:41
オリジナル
440 人が閲覧しました

Understanding React New Hooks

React 19 では、アプリケーションでのフォームの処理方法やオプティミスティックな更新の管理方法に革命をもたらす、いくつかの強力な新しいフックが導入されています。このブログでは、React アプリケーションの応答性を高め、ユーザーフレンドリーにする 3 つのフックである useFormStatus、useActionState、useOptimistic について説明します。

useFormStatus: 強化されたフォーム処理

useFormStatus フックは、フォーム送信に関するリアルタイムの情報を提供し、応答性の高いアクセシブルなフォームの作成を容易にします。このフックが React 18 のフォーム処理機能をどのように改善するかを見てみましょう。

例 1: 基本的なフォームの読み込み状態

function SubmitButton() {
  const { pending } = useFormStatus();

  return (
    <button disabled={pending}>
      {pending ? 'Submitting...' : 'Submit'}
    </button>
  );
}

function SignupForm() {
  return (
    <form action={async (formData) => {
      await submitSignupData(formData);
    }}>
      <input name="email" type="email" />
      <input name="password" type="password" />
      <SubmitButton />
    </form>
  );
}
ログイン後にコピー

React 18 では、useState を使用して読み込み状態を手動で管理する必要があります。新しい useFormStatus フックはこれを自動的に処理し、定型コードを削減します。

例 2: 複数のフォーム状態

function FormStatus() {
  const { pending, data, method } = useFormStatus();

  return (
    <div role="status">
      {pending && <span>Submitting via {method}...</span>}
      {!pending && data && <span>Last submission: {new Date().toLocaleString()}</span>}
    </div>
  );
}

function ContactForm() {
  return (
    <form action={async (formData) => {
      await submitContactForm(formData);
    }}>
      <textarea name="message" />
      <FormStatus />
      <SubmitButton />
    </form>
  );
}
ログイン後にコピー

例 3: フォーム検証ステータス

function ValidationStatus() {
  const { pending, validationErrors } = useFormStatus();

  return (
    <div role="alert">
      {validationErrors?.map((error, index) => (
        <p key={index} className="error">{error}</p>
      ))}
    </div>
  );
}

function RegistrationForm() {
  return (
    <form action={async (formData) => {
      const errors = validateRegistration(formData);
      if (errors.length) throw errors;
      await register(formData);
    }}>
      <input name="username" />
      <input name="email" type="email" />
      <ValidationStatus />
      <SubmitButton />
    </form>
  );
}
ログイン後にコピー

例 4: 複数ステップのフォームの進行状況

function FormProgress() {
  const { pending, step, totalSteps } = useFormStatus();

  return (
    <div className="progress-bar">
      <div 
        className="progress" 
       >



<h3>
  
  
  Example 5: File Upload Progress
</h3>



<pre class="brush:php;toolbar:false">function UploadProgress() {
  const { pending, progress } = useFormStatus();

  return (
    <div>
      {pending && progress && (
        <div className="upload-progress">
          <div 
            className="progress-bar" 
           >



<h2>
  
  
  useActionState: Managing Action Results
</h2>

<p>The useActionState hook provides a way to track the state of form actions and server mutations, making it easier to handle success and error states.</p>

<h3>
  
  
  Example 1: Basic Action State
</h3>



<pre class="brush:php;toolbar:false">function SubmissionStatus() {
  const state = useActionState();

  return (
    <div>
      {state.status === 'success' && <p>Submission successful!</p>}
      {state.status === 'error' && <p>Error: {state.error.message}</p>}
    </div>
  );
}

function CommentForm() {
  return (
    <form action={async (formData) => {
      await submitComment(formData);
    }}>
      <textarea name="comment" />
      <SubmissionStatus />
      <SubmitButton />
    </form>
  );
}
ログイン後にコピー

例2: 行動履歴

function ActionHistory() {
  const state = useActionState();

  return (
    <div>
      <h3>Recent Actions</h3>
      <ul>
        {state.history.map((action, index) => (
          <li key={index}>
            {action.type} - {action.timestamp}
            {action.status === 'error' && ` (Failed: ${action.error.message})`}
          </li>
        ))}
      </ul>
    </div>
  );
}
ログイン後にコピー

例 3: 再試行メカニズム

function RetryableAction() {
  const state = useActionState();

  return (
    <div>
      {state.status === 'error' && (
        <button 
          onClick={() => state.retry()}
          disabled={state.retrying}
        >
          {state.retrying ? 'Retrying...' : 'Retry'}
        </button>
      )}
    </div>
  );
}
ログイン後にコピー

例 4: アクションキュー

function ActionQueue() {
  const state = useActionState();

  return (
    <div>
      <h3>Pending Actions</h3>
      {state.queue.map((action, index) => (
        <div key={index}>
          {action.type} - Queued at {action.queuedAt}
          <button onClick={() => action.cancel()}>Cancel</button>
        </div>
      ))}
    </div>
  );
}
ログイン後にコピー

例 5: アクションの統計

function ActionStats() {
  const state = useActionState();

  return (
    <div>
      <h3>Action Statistics</h3>
      <p>Success Rate: {state.stats.successRate}%</p>
      <p>Average Duration: {state.stats.avgDuration}ms</p>
      <p>Total Actions: {state.stats.total}</p>
    </div>
  );
}
ログイン後にコピー

useOptimistic: スムーズな UI アップデート

useOptimistic フックを使用すると、サーバーの応答を待機している間に UI を即時更新できるため、より応答性の高いユーザー エクスペリエンスが作成されます。

例 1: 楽観的な ToDo リスト

function TodoList() {
  const [todos, setTodos] = useState([]);
  const [optimisticTodos, addOptimisticTodo] = useOptimistic(
    todos,
    (state, newTodo) => [...state, newTodo]
  );

  async function addTodo(formData) {
    const newTodo = {
      id: Date.now(),
      text: formData.get('todo'),
      completed: false
    };

    addOptimisticTodo(newTodo);
    await saveTodo(newTodo);
  }

  return (
    <div>
      <form action={addTodo}>
        <input name="todo" />
        <button type="submit">Add Todo</button>
      </form>
      <ul>
        {optimisticTodos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </div>
  );
}
ログイン後にコピー

例 2: 楽観的な「いいね!」ボタン

function LikeButton({ postId, initialLikes }) {
  const [likes, setLikes] = useState(initialLikes);
  const [optimisticLikes, addOptimisticLike] = useOptimistic(
    likes,
    (state) => state + 1
  );

  async function handleLike() {
    addOptimisticLike();
    await likePost(postId);
  }

  return (
    <button onClick={handleLike}>
      {optimisticLikes} Likes
    </button>
  );
}
ログイン後にコピー

例 3: 楽観的なコメント スレッド

function CommentThread({ postId }) {
  const [comments, setComments] = useState([]);
  const [optimisticComments, addOptimisticComment] = useOptimistic(
    comments,
    (state, newComment) => [...state, newComment]
  );

  async function submitComment(formData) {
    const comment = {
      id: Date.now(),
      text: formData.get('comment'),
      pending: true
    };

    addOptimisticComment(comment);
    await saveComment(postId, comment);
  }

  return (
    <div>
      <form action={submitComment}>
        <textarea name="comment" />
        <button type="submit">Comment</button>
      </form>
      {optimisticComments.map(comment => (
        <div key={comment.id}>



<h3>
  
  
  Example 4: Optimistic Shopping Cart
</h3>



<pre class="brush:php;toolbar:false">function ShoppingCart() {
  const [cart, setCart] = useState([]);
  const [optimisticCart, updateOptimisticCart] = useOptimistic(
    cart,
    (state, update) => {
      const { type, item } = update;
      switch (type) {
        case 'add':
          return [...state, item];
        case 'remove':
          return state.filter(i => i.id !== item.id);
        case 'update':
          return state.map(i => i.id === item.id ? item : i);
        default:
          return state;
      }
    }
  );

  async function updateCart(type, item) {
    updateOptimisticCart({ type, item });
    await saveCart({ type, item });
  }

  return (
    <div>
      {optimisticCart.map(item => (
        <div key={item.id}>
          {item.name} - ${item.price}
          <button onClick={() => updateCart('remove', item)}>Remove</button>
        </div>
      ))}
    </div>
  );
}
ログイン後にコピー

例 5: 楽観的なユーザー設定

function UserSettings() {
  const [settings, setSettings] = useState({});
  const [optimisticSettings, updateOptimisticSetting] = useOptimistic(
    settings,
    (state, update) => ({
      ...state,
      [update.key]: update.value
    })
  );

  async function updateSetting(key, value) {
    updateOptimisticSetting({ key, value });
    await saveSettings({ [key]: value });
  }

  return (
    <div>
      <div>
        <label>
          Theme:
          <select 
            value={optimisticSettings.theme} 
            onChange={e => updateSetting('theme', e.target.value)}
          >
            <option value="light">Light</option>
            <option value="dark">Dark</option>
          </select>
        </label>
      </div>
      <div>
        <label>
          Notifications:
          <input 
            type="checkbox"
            checked={optimisticSettings.notifications}
            onChange={e => updateSetting('notifications', e.target.checked)}
          />
        </label>
      </div>
    </div>
  );
}
ログイン後にコピー

アプリケーションでこれらのフックを使用する場合は、React の公式ドキュメントで最新情報とベスト プラクティスを必ず確認してください。

コーディングを楽しんでください!

以上がReact の新しいフックを理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート