繁体   English   中英

React 的问题不更新 state(挂钩)

[英]Trouble with React not updating state (hooks)

我有一个 memory 小游戏,我正在构建它来学习 React。 这个想法是,您单击一个图块,它会被打乱,然后您尝试选择一个您尚未选择的图块。 问题是我似乎无法获取我的内部 state,之前已经看到它更新了磁贴。

这是我的组件:

const Gameboard = (props) => {
  const [tiles, setTiles] = useState([]);
  const [currentScore, setCurrentScore] = useState(0);
  const [highScore, setHighScore] = useState(0);
  const [previouslySeen, setPreviouslySeen] = useState([]);

  const handleClick = (evt) => {
    const tile = evt.target;
    if (!previouslySeen.includes(tile)) {
      setCurrentScore(current => current + 1);
      props.setCurrentScore(current => current + 1);
      setPreviouslySeen([...previouslySeen, tile]);
    } else {
      alert("Game over, thanks for playing!");
      if (currentScore > highScore) {
        setHighScore(currentScore);
        props.setHighScore(currentScore);
      }
      setCurrentScore(0);
      props.setCurrentScore(0);
      setPreviouslySeen([]);
    }
  };

  const generateTiles = (tileCount) => {
    return [...Array(tileCount).keys()].map((n) => {
      return <Tile key={n} number={n} handleClick={handleClick} />;
    });
  };

  const shuffleTiles = (tiles) => {
    let tilesCopy = [...tiles];

    for (let i = tilesCopy.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * i);
      const temp = tilesCopy[i];
      tilesCopy[i] = tilesCopy[j];
      tilesCopy[j] = temp;
    }

    return tilesCopy;
  };

  useEffect(() => {
    const initialTiles = generateTiles(props.tileCount);
    setTiles(shuffleTiles(initialTiles));
  }, []);

  useEffect(() => {
    setTiles((oldTiles) => {
      const newTiles = shuffleTiles(oldTiles);
      return newTiles;
    });
  }, [currentScore, highScore]);

  return <div className="Gameboard">{tiles}</div>;
};

handleClick方法被传递到各个Tile组件中,并且仅使用onClick进行调用。 handleClick method is what is giving me trouble, it seems as if it doesn't ever update过 previouslySeen`,我在父组件中设置高分以使其反映在 UI 中时遇到类似的问题。 你应该如何在 React 中处理这样的更新?

试试这个:

const handleClick = (evt) => {
const tile = evt.target;
if (!previouslySeen.includes(tile)) {
  setCurrentScore(current => current + 1);
  props.setCurrentScore(current => current + 1);
  // Change the following line:
  setPreviouslySeen(previousState => [...previousState, tile]);
} else {

此外,您将从父属性声明状态中获取setCurrentScore, setHighScore

  const [currentScore, setCurrentScore] = useState(0);
  const [highScore, setHighScore] = useState(0);

所以基本上你保持两个独立的currentScorehighScore状态 - 一个在Gameboard组件中,一个在它的父组件中。 最好从Gameboard中删除这state个变量和setter,直接从parent props中获取。

事实证明,这是因为我将 JSX 元素直接存储在 state 中。删除它并仅存储平铺值(纯 JS 字符串)解决了 state 未正确更新的问题。 真是陷阱!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM