簡體   English   中英

如何在單獨的 Function 中更新 div 的內容?

[英]How to Update the Content of a div in a Separate Function?

我對 JavaScript 很陌生,所以如果這個問題措辭不當或答案很明顯,我深表歉意。 我決定做一個排序可視化項目作為練習。 我目前正在制作的內容是基於 Clément Mihailescu 的這段視頻

在我的程序中,我有我的渲染 function ,它采用具有隨機值的數組,並使用 array.map() 生成具有根據值高度的條形列,以及條形的顏色:

render() {
    const {array} = this.state;

    return (
      <div className="array-container">
        {array.map((value, idx) => (
          <div
            className="array-bar"
            key={idx}
            style={{
              backgroundColor: PRIMARY_COLOR,
              height: `${value}px`,
            }}></div>
        ))}
        <button onClick={() => this.resetArray()}>Generate New Array</button>
        <button onClick={() => this.mergeSort()}>Merge Sort</button>
        <button onClick={() => this.quickSort()}>Quick Sort</button>
        <button onClick={() => this.heapSort()}>Heap Sort</button>
        <button onClick={() => this.bubbleSort()}>Bubble Sort</button>
      </div>
    );
  }
}

在底部,我有一些在我的數組欄上執行特定排序算法的按鈕和一個“生成新數組”按鈕。 結果最終看起來像這樣

我的問題是我的快速排序算法最終將我的條形圖的 colors 更改為紫色,以指示數組已排序,但我希望能夠在按下“生成新數組”按鈕時將它們更改回原來的顏色. 現在,我的“重置數組” function 生成一個帶有隨機數的新數組,然后將我的主數組的 state 設置為等於:

 resetArray() {
    const array = [];
    for (let i = 0; i < NUMBER_OF_ARRAY_BARS; i++) {
      array.push(randomIntFromInterval(5, 400));
    }  
    this.setState({array});  
 }

所以這成功生成了我的新數組,但顏色沒有被更新

我假設要按照我想要的方式改變數組條的顏色,我應該在這個 resetArray function 中生成我的條,然后在我的原始渲染中簡單地調用它。 問題是我對 JavaScript 的有限理解使得這個看似簡單的修復變得相當困難。 語法明智我只是不知道最好的方法是什么。 如果有人能引導我朝着正確的方向前進,我將不勝感激。 對不起,很長的帖子,我想徹底描述我的問題。

更新描述快速排序算法

這部分代碼不是很好,可能可以更有效地完成。 對於我的 QuickSort 調用,我為條形顏色/值的更改生成了一個單獨的“動畫”數組。 我循環遍歷這個數組,並根據我到達一個字符串(新顏色)還是一個數字(新值)來相應地編輯我的數組索引。

  quickSort() {

    const animations = getQuickSortAnimations(this.state.array);
    
      for (let i = 0; i < animations.length; i++){
        const arrayBars = document.getElementsByClassName('array-bar');
        let barIndex;
        let barStyle;
        // break in the case of array being out of bounds
        if (animations[i][0] >= this.state.array.length) { break; }

          // switch statement performs either height change or color change
          // depending on which is passed through to animations
          switch(typeof animations[i][1]){
            // color change
            case "string":
              barIndex = animations[i][0];
              barStyle = arrayBars[barIndex].style;
              setTimeout(() => {
                barStyle.backgroundColor = animations[i][1];
              }, i * ANIMATION_SPEED_MS);
              break;
              //height change
            case "number":
              barIndex = animations[i][0];
              barStyle = arrayBars[barIndex].style;
              setTimeout(() => {
                barStyle.height = `${animations[i][1]}px`
              }, i * ANIMATION_SPEED_MS);
          }
     }

一開始,我將我的動畫數組設置為“getQuickSortAnimations”,其中我的實際算法發生在一個單獨的文件中。 這是我對動畫數組執行推送的地方,該數組對數組條進行視覺排序:

export function getQuickSortAnimations (array) {
    const animations = [];
    if (array.length <= 1) { return array; }
    quickSort(array, 0, array.length-1, animations)
    return animations;
}

function quickSort (array, lowIndex, highIndex, animations){
    if (lowIndex >= highIndex) { 
        animations.push([lowIndex, 'purple']);
        return; 
    }
    let pivot = array[highIndex];
    let leftPtr = partition(array, lowIndex, highIndex, pivot, animations);
    quickSort(array, lowIndex, leftPtr-1, animations);
    quickSort (array, leftPtr+1, highIndex, animations);
}

function partition (array, lowIndex, highIndex, pivot, animations){
    let leftPtr = lowIndex;
    let rightPtr = highIndex-1;
    // Coloring our first instance of leftPtr and our Pivot(highIndex)
    animations.push([highIndex, 'yellow']);
    animations.push([leftPtr, 'red']);
    animations.push([rightPtr, 'red']);
    while (leftPtr < rightPtr) {
        while ((array[leftPtr] <= pivot) && (leftPtr < rightPtr)){
            // Send rightPtr to animations once to decolor
            animations.push([leftPtr, 'turquoise']);
            leftPtr++;
            // Send new leftPtr to animations to color new array bar
            animations.push([leftPtr, 'red']);
        }
        while ((array[rightPtr] >= pivot) && (leftPtr < rightPtr)){
            // Send rightPtr to animations once to decolor
            animations.push([rightPtr, 'turquoise']);
            rightPtr--;
            // Send new rightPtr to animations to color new array bar
            animations.push([rightPtr, 'red']);
        }
        // temp variable holds the value of our leftPtr index while we perform swap
        let temp = array[leftPtr];
        // swap our leftPtr with our rightPtr in animations
        animations.push([leftPtr, array[rightPtr]]);
        // swap our rightPtr with our leftPtr in animations using temp
        animations.push([rightPtr, temp]);
        // same swap as above but with the our actual array
        [array[leftPtr], array[rightPtr]] = [array[rightPtr], array[leftPtr]];
    }
    animations.push([highIndex, 'turquoise']);
    if (array[leftPtr] > array[highIndex]) {
        // temp variable holds the value of our leftPtr index while we perform swap
        let temp = array[leftPtr];
        // swap our leftPtr with our highIndex in animations
        animations.push([leftPtr, array[highIndex]]);
        // swap our highIndex with our leftPtr in animations using temp
        animations.push([highIndex, temp]);
        // same swap as above but with the our actual array
        [array[leftPtr], array[highIndex]] = [array[highIndex], array[leftPtr]];
        animations.push([leftPtr, 'purple']);
    }
    else {
        leftPtr = highIndex;
        animations.push([leftPtr, 'purple']);
    }
    return leftPtr;
}

好的,所以對於反應(或角度)永遠不要嘗試在反應生命周期之外操作 DOM, document.getElementsByClassName適用於您的情況以更改顏色,但要將其更改回來,您需要使用相同的方法手動執行,這不是什么你必須與反應有關。 你需要做的是:

准備要渲染的數據,完成一個,不僅是數字數組,還有對象數組{value, bgColor (for example}},所以數組中的每個條目都會有它需要渲染的所有數據,假設每個的項目將有不同的顏色。

constructor(props) {
  super(props);
  const arr = [1, 4, 85, 0, 1, 3, 5, 6, 4, 7, 1, 32, 1, 56, 84];
  const arrayToRender = this.getArrayToRender(arr, PRIMARY_COLOR);

  this.state = {
    array: arr,
    arrayToRender: arrayToRender
  };
}

getArrayToRender(array, color) {
  return array.map((x) => {
    return { value: x, bgColor: color };
  });
}

並將渲染方法更改為以下內容:

render() {
  const { arrayToRender } = this.state;

  return (
    <div>
      <div className="array-container">
        {arrayToRender.map((x, idx) => (
          <div
            className="array-bar"
            key={idx}
            style={{
              backgroundColor: x.bgColor, // <- Here!
              height: `${x.value}px`
            }}
          ></div>
        ))}
      </div>
      <div>
        <button onClick={() => this.resetColor()}>Reset Color</button>
        <button onClick={() => this.resetArray()}>Generate New Array</button>
        <button onClick={() => this.mergeSort()}>Merge Sort</button>
        <button onClick={() => this.quickSort()}>Quick Sort</button>
        <button onClick={() => this.heapSort()}>Heap Sort</button>
        <button onClick={() => this.bubbleSort()}>Bubble Sort</button>
      </div>
    </div>
  );
}

注意我添加了一個“重置顏色”按鈕

resetColor() {
  // You can mutate state objects as is (dangerous)
  this.state.arrayToRender.forEach((x) => (x.bgColor = PRIMARY_COLOR));
  // But you need to re-set the state to make react reflect the changes
  this.setState((prev) => ({ ...prev }));
}

此外, quickSort方法也需要進行一些更改才能不使用 DOM 函數。

quickSort() {
  const animations = getQuickSortAnimations(this.state.array);

  for (let i = 0; i < animations.length; i++) {
    const curr = this.state.arrayToRender[animations[i][0]];
    switch (typeof animations[i][1]) {
      case "string":
        setTimeout(() => {
          curr.bgColor = animations[i][1];
          this.setState((prev) => ({ ...prev }));
        }, i * ANIMATION_SPEED_MS);
        break;
      case "number":
        setTimeout(() => {
          curr.value = animations[i][1];
          this.setState((prev) => ({ ...prev }));
        }, i * ANIMATION_SPEED_MS);
        break;
      default:
        console.error("Welp");
        break;
    }
  }
  // This will reset colors to default one after algo run + 2 sec
  const totalDelay = animations.length * ANIMATION_SPEED_MS + 2000; // added 2 seconds
  setTimeout(() => {
    this.resetColor();
  }, totalDelay);
}

編輯 React 基礎類組件(分叉)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM