如何使用 useEffect 睡眠组件

问题描述 投票:0回答:1

我正在尝试实现排序算法并构建 React 应用程序以显示未排序的数组如何随着每次迭代而变化。

为了使其可见,应用程序必须在每次迭代后停止一段时间,我正在尝试使用 setTimeout 函数和 useEffect 挂钩来执行此操作,但它不起作用。

这是我的组件:

import { useEffect, useState } from "react"
import { SortAlgorithms } from "../Utils/Sort"


export default function SortingBoard(){
    const [board, setBoard] = useState([10,9,8,7,6,5,4,3,2,1])
    const [delay, setDelay] = useState(500)
    const [algorithm, setAlgorithm] = useState(() => SortAlgorithms[0])
    const [isIterating, setIsIterating] = useState(false)

    useEffect(() => {
        async function sleep(){
            const timer = new Promise(r => setTimeout(r, delay));
            await timer
        }

        sleep()
    }, [board])

    const handleSort = async () => {
        setIsIterating(true)
        algorithm({board, setBoard})
        setIsIterating(false)
    }

    return (
        <div className="bord-layout">
            <div className="bord">
                {board.map( (item, idx) =>{
                    return <h1 key={idx}>{item}</h1>
                })}
            </div>

            <div className="bord-options">
                <select name="algorithms" onChange={e => setAlgorithm(() => SortAlgorithms[e.target.value])}>
                    <option value={0}>Bubble Sort</option>
                    <option value={1}>Sellection Sort</option>
                </select>
                <button disabled={isIterating} onClick={handleSort}>
                    Sort
                </button>
            </div>
        </div>
    )
}

这里是排序函数:

function BubbleSort({board, setBoard}){
    for(let i = 0; i < board.length; i++){
        for(let j = 0; j < board.length - 1; j++){
            if(board[j] > board[j + 1]){
                const temp = board[j]

                board[j] = board[j + 1]
                board[j + 1] = temp
                setBoard([...board])
            }
        }
    }
}

function SelectionSort({board, setBoard}){
    for(let i = 0; i < board.length; i++){
        let min = i
        for(let j = i + 1; j < board.length; j++){
            if( board[j] < board[min]){
                min = j
            }
        }
        const temp = board[i]
        board[i] = board[min]
        board[min] = temp
        setBoard([...board])
    }
}

export const SortAlgorithms = [BubbleSort, SelectionSort]

特别是,它在每次迭代时调用 setTimeout 但不等待它们解决。

在这种情况下我应该使用 useEffect 和 setTimeout 还是我可以使用其他方法?

reactjs react-hooks async.js
1个回答
0
投票

您当前实现的问题是排序算法是同步的,您正试图在 useEffect 中使用 setTimeout,这实际上不会影响排序算法的同步执行。要解决此问题,您可以在排序算法本身中使用 setTimeout 并使它们异步。

你的排序算法应该是这样的:

async function BubbleSort({ board, setBoard }) {
 const delay = 500;
 const newBoard = [...board];

 for (let i = 0; i < newBoard.length; i++) {
  for (let j = 0; j < newBoard.length - 1; j++) {
    if (newBoard[j] > newBoard[j + 1]) {
      const temp = newBoard[j];

      newBoard[j] = newBoard[j + 1];
      newBoard[j + 1] = temp;

      await new Promise((resolve) => setTimeout(resolve, delay));
      setBoard([...newBoard]);
    }
   }
  }
 }

async function SelectionSort({ board, setBoard }) {
 const delay = 500;
 const newBoard = [...board];

 for (let i = 0; i < newBoard.length; i++) {
  let min = i;
  for (let j = i + 1; j < newBoard.length; j++) {
    if (newBoard[j] < newBoard[min]) {
      min = j;
    }
  }
  const temp = newBoard[i];
  newBoard[i] = newBoard[min];
  newBoard[min] = temp;

  await new Promise((resolve) => setTimeout(resolve, delay));
  setBoard([...newBoard]);
 }
}

您现在可以删除具有睡眠功能的 useEffect 块,因为它不再需要了。此外,您需要使 handleSort 异步并等待对算法的调用:

const handleSort = async () => {
 setIsIterating(true);
 await algorithm({ board, setBoard });
 setIsIterating(false);
};

进行这些更改时,排序算法现在将在每次迭代之间暂停指定的延迟,并且组件将相应地重新渲染。

© www.soinside.com 2019 - 2024. All rights reserved.