簡體   English   中英

為什么在 state 更改后 React 沒有渲染? 【功能組件】

[英]Why React is not rendering after change in state? [functional component]

import React, {useState, useEffect} from 'react';

import MakeCard from './MakeCard.js';

export default function GameCards(props) {
  const [images, setImages] = useState([{}]);

  // Render component after fetching images
  useEffect(() => {
    getImages(props.cards).then(images => setImages(images));
  }, [props.cards]);

  // shuffle images and update state.
  const shuffleCards = (e) => {
    console.log("clicked");
    let newImages = images;
    for (let i = newImages.length - 1; i >= 0; i--) {
      let temp, j;
      j = Math.floor(Math.random() * i);
      temp = newImages[i];
      newImages[i] = images[j];
      newImages[j] = temp;
    }
    setImages(newImages);
    console.log("newImages: ", images);
  }

  if (images.length === 0) {
    return (<h1>Loading...</h1>)
  } else {
    return (<div>
      {
        images.map((image, i) => <MakeCard image={image} key={i}
          // shuffleCards={shuffleCards} 
        />)
      }
    </div>)
  }
}

所以我試圖做出一個Memory_Card_Game的反應,但是當我洗牌圖像數組(當用戶點擊圖像時)這是一個 state 變量。 React 不渲染。 我在文檔中讀到了當組件的 state 發生更改時會更新虛擬 DOM 樹的文檔。 為什么更改圖像數組后不渲染?

const [images, setImages] = useState([{}]);

您正在改變原始圖像數組。

您設置 newImages = images (這只是參考而不是副本),然后更改 newImages 中的位置。

這有效地改變了原始數組,因此當 react 將傳遞給 setImages 的 newImages 與之前的圖像進行比較時,它們是相同的數組,因此不會檢測到任何變化。

你可以用let newImages = [...images];來修復它。

React 使用Object.is比較算法來檢查 state 變量的變化,在這種情況下images是一個Array ,所以不要改變它的值,你應該每次都創建一個新的,例如:

const newImages = [...images]; // instead of "let newImages = images";

您的 newImages 數組基本上是相同的數組(相同的引用)。 嘗試這個:

const shuffleCards = (e) => {
    console.log("clicked");
    const newImages = [...images];
    for(let i = newImages.length - 1; i >= 0; i--){
      let temp, j;
      j = Math.floor(Math.random() * i);
      temp = newImages[i];
      newImages[i] = images[j];
      newImages[j] = temp;
    }
    setImages(newImages);
    console.log("newImages: ", images);
  }

這樣我們就創建了圖像數組的克隆。

由於您正在改變數組並使用相同的數組引用設置 state,因此 react 選擇不重新渲染組件。 發生這種情況是因為 React 使用Object.is比較,同時檢查是否需要在 setState 之后發生重新渲染。 這個想法是返回數組的新引用,而不是改變原始數組。 您可以通過使用擴展語法淺復制原始數組來使其工作

const shuffleCards = (e) => {
    console.log("clicked");
    // Shallow clone the array
    let newImages = [...images];
    for(let i = newImages.length - 1; i >= 0; i--){
      let temp, j;
      j = Math.floor(Math.random() * i);
      temp = newImages[i];
      newImages[i] = images[j];
      newImages[j] = temp;
    }
    setImages(newImages);
    console.log("newImages: ", images);
  }

暫無
暫無

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

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