Home >Web Front-end >JS Tutorial >Returning JSX from React Server Actions

Returning JSX from React Server Actions

王林
王林Original
2024-08-31 06:34:37674browse

Did you know that Next.js Server Actions can return JSX markup instead of raw JSON data?

While it's not explicitly mentioned in the docs, I was pleasantly surprised that it works.

Example

I have a page that renders users list with server action:

export default function Page() {
  async function loadUsersAction() {
    "use server";

    return [
      { name: "John", age: 30 },
      { name: "Jane", age: 25 },
      { name: "Doe", age: 40 },
    ];
  }

  return <UsersList loadUsersAction={loadUsersAction} />;
}

UsersList component loads users by button click:

export default function UsersList({ loadUsersAction }) {
  const [users, setUsers] = useState();

  const onClick = async () => {
    const data = await loadUsersAction();
    setUsers(data);
  };

  return (
    <>
      <button onClick={onClick}>Load users</button>
      <ul>
        {users?.map((user) => (
          <li key={user.name}>
            {user.name} - {user.age}
          </li>
        ))}
      </ul>
    </>
  );
}

Demo:

Returning JSX from React Server Actions

Now I change server action to return JSX with rendered users:

async function loadUsersAction() {
  "use server";

  const users = [
    { name: "John", age: 30 },
    { name: "Jane", age: 25 },
    { name: "Doe", age: 40 },
  ];

  return (
    <ul>
      {users?.map((user) => (
        <li key={user.name}>
          {user.name} - {user.age}
        </li>
      ))}
    </ul>
  );
}

And in UsersList component just render server action response:

export default function UsersList({ loadUsersAction }) {
  const [users, setUsers] = useState();

  const onClick = async () => {
    const data = await loadUsersAction();
    setUsers(data);
  };

  return (
    <>
      <button onClick={onClick}>Load users</button>
      {users}
    </>
  );
}

In browser everything works in the same way!

Note on errors handling

What if server action throws an error? When it returns a JSON data, we can catch that error inside action and return it in own format like:

{ error: "my error" }

When returning JSX, we can let error throw and catch it with the nearest error boundary on the client. Per React docs, server action calls outside the

component should be wrapped into Transition for proper errors handling.
The final code of UsersList component:

export default function UsersList({ loadUsersAction }) {
  const [isPending, startTransition] = useTransition();
  const [users, setUsers] = useState();

  const onClick = () => {
    startTransition(async () => {
      const data = await loadUsersAction();
      setUsers(data);
    });
  };

  return (
    <>
      <button onClick={onClick}>Load users</button>
      {isPending ? <div>Loading users...</div> : users}
    </>
  );
}

Additionally, I utilize isPending flag to show message while loading users.

Demo:
Returning JSX from React Server Actions

Hope it would be helpful.
Thanks for reading and happy coding! ❤️

The above is the detailed content of Returning JSX from React Server Actions. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn