0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React18のTransitionを試す @yukilulu0229

Last updated at Posted at 2024-02-13

startTransition

startTransition を使うことで、UI をブロックせずに state を更新することができます。

使い方

App.jsx
import React, {startTransition, useState} from 'react';
// import React, {useState, useTransition} from 'react';
import Avatar from "./Avatar.tsx";

type Task = {
  id: number;
  title: string;
  assignee: string;
}

const member:{} = {
  a: "A",
  b: "B",
  c: "C"
}

const generateDummyTasks = (): Task[] => {
  return Array(10000).fill(null).map((_, index) => {
    const addedIndex = index + 1;

    return {
      id: addedIndex,
      title: `task: ${addedIndex}`,
      assignee: addedIndex % 3 === 0 ? member.a : addedIndex % 2 === 0 ? member.b : member.c
    }
  });
}

const filteringAssignee = (assignee: string) => {
  if (assignee === "") return tasks;

  return tasks.filter((task) => task.assignee === assignee);
}

const tasks:Task[] = generateDummyTasks();

const Transition = () => {
  const [selectedAssignee, setSelectedAssign] = useState<string>("")
  const [taskList, setTaskList] = useState<Task[]>(tasks);

  const onClickAssign = (assignee: string) => {
    setSelectedAssign(assignee);
    // 重たい処理を分離する;
    startTransition(() => {
      setTaskList(filteringAssignee(assignee));
    })
  }

  return (
    <div>
      <h2>transition</h2>

      <div style={{display: "flex", justifyContent: "center"}}>
        <Avatar isSelected={selectedAssignee === member.a} onClick={onClickAssign}>{member.a}</Avatar>
        <Avatar isSelected={selectedAssignee === member.b} onClick={onClickAssign}>{member.b}</Avatar>
        <Avatar isSelected={selectedAssignee === member.c} onClick={onClickAssign}>{member.c}</Avatar>
      </div>

      <button onClick={() => onClickAssign("")}>リセット</button>

      {taskList.map((task) => (
        <div key={task.id} style={{width: "300px", margin: "auto", background: "lavender"}}>
          <p>タイトル: {task.title}</p>
          <p>担当: {task.assignee}</p>
        </div>
      ))}
    </div>
  );
};

export default Transition;

const onClickAssign = (assignee: string) => {
    setSelectedAssign(assignee);
    // 重たい処理を分離する;
    startTransition(() => {
      setTaskList(filteringAssignee(assignee));
    })
  }

重たい処理を分離する

useTransition

useTransition は、UI をブロックせずに state を更新するための React フックです

使い方

App.tsx
import React, {useState, useTransition} from 'react';
import Avatar from "./Avatar.tsx";

type Task = {
  id: number;
  title: string;
  assignee: string;
}

const member:{} = {
  a: "A",
  b: "B",
  c: "C"
}

const generateDummyTasks = (): Task[] => {
  return Array(10000).fill(null).map((_, index) => {
    const addedIndex = index + 1;

    return {
      id: addedIndex,
      title: `task: ${addedIndex}`,
      assignee: addedIndex % 3 === 0 ? member.a : addedIndex % 2 === 0 ? member.b : member.c
    }
  });
}

const filteringAssignee = (assignee: string) => {
  if (assignee === "") return tasks;

  return tasks.filter((task) => task.assignee === assignee);
}

const tasks:Task[] = generateDummyTasks();

const Transition = () => {
  const [selectedAssignee, setSelectedAssign] = useState<string>("")
  const [taskList, setTaskList] = useState<Task[]>(tasks);
  const [isPending, startTransition] = useTransition();

  const onClickAssign = (assignee: string) => {
    setSelectedAssign(assignee);
    // 重たい処理
    // setTaskList(filteringAssignee(assignee))

    // 重たい処理を分離する;
    startTransition(() => {
      setTaskList(filteringAssignee(assignee));
    })
  }

  return (
    <div>
      <h2>transition</h2>

      <div style={{display: "flex", justifyContent: "center"}}>
        <Avatar isSelected={selectedAssignee === member.a} onClick={onClickAssign}>{member.a}</Avatar>
        <Avatar isSelected={selectedAssignee === member.b} onClick={onClickAssign}>{member.b}</Avatar>
        <Avatar isSelected={selectedAssignee === member.c} onClick={onClickAssign}>{member.c}</Avatar>
      </div>

      <button onClick={() => onClickAssign("")}>リセット</button>

      {taskList.map((task) => (
        <div key={task.id} style={{width: "300px", margin: "auto", background: "lavender", opacity: isPending ? 0.5 : 1}}>
          <p>タイトル: {task.title}</p>
          <p>担当: {task.assignee}</p>
        </div>
      ))}
    </div>
  );
};

export default Transition;

const [isPending, startTransition] = useTransition();

宣言する

const onClickAssign = (assignee: string) => {
    setSelectedAssign(assignee);
    // 重たい処理を分離する;
    startTransition(() => {
      setTaskList(filteringAssignee(assignee));
    })
  }

重たい処理を分離する

<div key={task.id} style={{width: "300px", margin: "auto", background: "lavender", opacity: isPending ? 0.5 : 1}}>

pendingの状態でUIに変化を付けることができる

useDeferredValue

コンポーネントが別れてるときとか?

useDeferredValue は、UI の一部の更新を遅延させるための React フックです。

TaskList.tsx

import React, {memo, useDeferredValue} from 'react';
import type {Task} from "./Transition.tsx";

type Props = {
  taskList: Task[];
}
const TaskList = memo(({taskList}: Props) => {
  const deferredTaskList = useDeferredValue(taskList)

  return (
    <>
      {deferredTaskList.map((task) => (
        <div key={task.id} style={{width: "300px", margin: "auto", background: "lavender"}}>
          <p>タイトル: {task.title}</p>
          <p>担当: {task.assignee}</p>
        </div>
      ))}
    </>
  );
});

export default TaskList;


 const deferredTaskList = useDeferredValue(taskList)

useDeferredValueに入れる

{deferredTaskList.map((task) => (

入れた変数で展開する

読み込み時間をわざと遅らせる関数

App.tsx
const sleep = (ms: number):Promise<any> => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  })
}

const fetchAlbums = async () => {
  const result = await axios.get<Album[]>("https://jsonplaceholder.typicode.com/albums").then(await sleep(5000));

  return result.data
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?