【问题标题】:Undefined state in child component using useContext使用 useContext 的子组件中的未定义状态
【发布时间】:2020-03-14 09:12:04
【问题描述】:

我正在使用 React 构建 snake game。蛇的坐标(snakeDots状态切片)每秒更新一次,新的状态应该反映在Snake组件中,它将蛇渲染到屏幕上。我正在使用useReduce,所以我可以同步更新状态,并且我正在使用 useContext 将状态传播到子组件。在第一次渲染时,我收到未定义状态(snakeDots)的错误。不明白为什么,因为状态具有初始值。任何人都可以解释一下吗?谢谢

App.js:

import React, { useState, useEffect, useReducer } from "react";
import Snake from "./Snake";
import Food from "./Food";

import { snakeContext } from "./contexts/snakeContext";

const getRandomCoordinates = () => {
  let min = 1;
  let max = 98;
  let x = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2;
  let y = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2;
  return [x, y];
};

function App() {
  const [snakeDots, dispatch] = useReducer(reducer, [
    [0, 0],
    [2, 0]
  ]);

  const [food, setFood] = useState(getRandomCoordinates());

  const [direction, setDirection] = useState("RIGHT");

  const [speed, setSpeed] = useState(200);

  useEffect(() => {
    setInterval(() => dispatch({ type: direction }), speed);
    document.onkeydown = onKeyDown;
  }, []);

  function onKeyDown(e) {
    e = e || window.event;
    switch (e.keyCode) {
      case 38:
        setDirection("UP");
        break;
      case 40:
        setDirection("DOWN");
        break;
      case 37:
        setDirection("LEFT");
        break;
      case 39:
        setDirection("RIGHT");
        break;
      default:
        console.log("wrong key");
    }
  }

  function reducer(snakeDots, action) {
    switch (action.type) {
      case "RIGHT":
        let head = snakeDots[snakeDots.length - 1];
        head = [head[0] + 2, head[1]];
        snakeDots.push(head);
        snakeDots.shift();
        return snakeDots;
      default:
        throw new Error();
    }
  }

  return (
    <div className="game-area">
      <snakeContext.Provider value={{ snakeDots, food }} />
        <Snake />
        <Food dot={food} />
      <snakeContext.Provider />
    </div>
  );
}

export default App;

Snake.jsx:

import React, { useContext } from "react";

import { snakeContext } from "./contexts/snakeContext";

export default function Snake () {
  debugger
  const { snakeDots } = useContext(snakeContext);
  debugger;
  return (
    <div>
      {snakeDots.map((dot, i) => {
        const style = {
          left: `${dot[0]}%`,
          top: `${dot[1]}%`
        };
        return <div className="snake-dot" key={i} style={style}></div>;
      })}
    </div>
  );
};

snakeContext.js:

import { createContext } from "react";
export const snakeContext = createContext();

编辑:

错误信息是: TypeError: Cannot read property 'snakeDots' of undefinedSnake.js 中,组件甚至不渲染,第 5 行。

【问题讨论】:

  • 什么确切地是错误,是哪一行抛出该错误?
  • 感谢@AlexWayne,刚刚在上面的问题中添加了错误消息

标签: reactjs react-hooks


【解决方案1】:

我看到了你的问题。您正在关闭第一个提供者并且不包装蛇组件,而是创建两个没有子提供者。将 App.js 中的返回改为:

  return (
    <div className="game-area">
      <snakeContext.Provider value={{ snakeDots, food }}>
        <Snake />
        <Food dot={food} />
      </snakeContext.Provider>
    </div>
  );

您当前拥有的内容(固定缩进以查看错误)

  return (
    <div className="game-area">
      {/* First provider */}
      <snakeContext.Provider value={{ snakeDots, food }} />

      <Snake />

      <Food dot={food} />

      {/* Second provider */}
      <snakeContext.Provider />
    </div>
  );

Snake 不是任何 Provider 的孩子,而是兄弟姐妹。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-12
    • 2020-08-06
    • 1970-01-01
    • 2021-11-12
    • 2022-10-08
    • 2022-01-24
    • 2021-08-29
    相关资源
    最近更新 更多