简体   繁体   English

当我尝试从数组中渲染对象时出现类型错误

[英]Type Error when i try to Render Objects out of an array

i get the following error when i try to load questions(Array) for a quiz from a db.json server.当我尝试从 db.json 服务器加载测验的问题(数组)时出现以下错误。

TypeError: this.state.questions[this.state.currentQuestion] is undefined类型错误:this.state.questions[this.state.currentQuestion] 未定义

here is a sandbox of my project (relevant classes are play_quiz.js and db.json https://codesandbox.io/s/kjllt?file=/quiz-project/server/db.json这是我项目的沙箱(相关类是 play_quiz.js 和 db.json https://codesandbox.io/s/kjllt?file=/quiz-project/server/db.json

the error occurs in line 79 of play_quiz.js错误发生在 play_quiz.js 的第 79 行

it worked just fine when i did it without the json server but not it seems to have some kind of problem recognising the content of the array.当我在没有 json 服务器的情况下执行它时它工作得很好但不是它似乎在识别数组内容时遇到某种问题。 I hope someone can help me我希望有一个人可以帮助我

As discussed in the comments, the issue is that when the component renders for the first time, this.state.questions is an empty array as set in the state's initial state.正如评论中所讨论的,问题是当组件第一次呈现时, this.state.questions是一个空数组,如状态初始 state 中所设置的那样。

Because of this, this.state.questions[0] returns undefined, until the API response finishes (which is started by getRandomizedQuestions() which is called by componentDidMount after the component has been rendered and mounted).因此, this.state.questions[0]返回 undefined,直到 API 响应完成(由getRandomizedQuestions()启动,在组件渲染和安装后由componentDidMount调用)。

You need to handle this case.你需要处理这种情况。 The way to solve it depends on how you want to solve it and what you want to show to the user while it's loading.解决它的方法取决于你想如何解决它以及你想在加载时向用户展示什么。 Here's a few solutions:这里有几个解决方案:

1. Just show "loading" until the array isn't empty. 1. 只显示“loading”直到数组不为空。

render() {
  if (this.state.questions.length < 1) {
    return <div className="quiz-window">Loading...</div>;
  }

  return (
    <div className="quiz-window">
      // ...
    </div>
  );
}

2. Use another ternary to show "loading" in the place of the block of JSX which depends on the array: 2. 在依赖于数组的 JSX 块的位置使用另一个三元组来显示“正在加载”:

render() {
  return (
    <div className="quiz-window">
      {this.state.showScore ? (
        <div className="score-section">
          korrekt beantwortet: {this.state.score} von{" "}
          {this.state.questions.length}
        </div>
      ) : this.state.questions.length > 0 ? (
        <>
          <div className="question-section">
            <div className="question-count">
              <span>Frage {this.state.currentQuestion + 1}</span>/
              {this.state.questions.length}
            </div>
            <div className="question-text">
              {this.state.questions[this.state.currentQuestion].title}
            </div>
          </div>
          <div className="answer-section">
            {this.state.questions[this.state.currentQuestion].answers.map(
              (answer) => (
                <button
                  onClick={() => this.handleAnswerOptionClick(answer.isCorrect)}
                >
                  {answer.title}
                </button>
              )
            )}
          </div>
        </>
      ) : (
        <p>Loading</p>
      )}
    </div>
  );
}

Alternatively, if it's possible that the API returns an empty array and you want to handle that as a separate case:或者,如果 API 可能返回一个空数组并且您想将其作为单独的情况处理:

3. Introduce state variable that tracks when the data is loading and show loading until it's done 3. 引入 state 变量跟踪数据何时加载并显示加载直到完成

class Play_quiz extends React.Component {
  state = {
    currentQuestion: 0,
    showScore: false,
    score: 0,
    questions: [],
    isLoading: true,
  };

  // ...

  getRandomizedQuestions = () => {
    const apiUrl = "http://localhost:3001/questions";
    fetch(apiUrl)
      .then((response) => response.json())
      .then(
        (result) => {
          console.log("From database:");
          console.log(result);

          let amountOfQuestions = result.length;
          let randomizedResult = [];
          for (let i = 0; i < amountOfQuestions; i++) {
            let randomIndex = Math.floor(Math.random() * result.length);
            randomizedResult.push(result[randomIndex]);
            result.splice(randomIndex, 1);
          }

          this.setState({
            questions: randomizedResult,
            isLoading: false
          });
          // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        },
        (error) => {
          console.log("An unexpected error occurred", error);
        }
      );
  };

  // ...

  render() {
    if (this.state.isLoading) {
      return <div className="quiz-window">Loading...</div>;
    }

    return (
      <div className="quiz-window">
        // ...
      </div>
    );
  }
}

See also: Why calling react setState method doesn't mutate the state immediately?另请参阅:为什么调用 react setState 方法不会立即改变 state?

暂无
暂无

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

相关问题 当我尝试渲染 EJS 页面时,我不断收到类型错误...,有人可以看看吗? - I keep getting a type error when I try to render an EJS page... ,can someone have a look? 当我尝试在我的 react.js 组件中迭代对象数组时,为什么会出现错误? - Why does error appear when I try to iterate array of objects in my react.js component? 当我尝试将接口分配给属性时出现类型错误 - getting type error when I try to assign interface to a property 当我尝试将打字稿代码编译为javascript时,得到** Type&#39;NodeListOf <Element> &#39;不是数组类型或字符串类型** - When i try to compile typescript code into javascript, getting **Type 'NodeListOf<Element>' is not an array type or a string type** 为什么当我下载我的数组并尝试获取它的长度时,它只是吐出数组的字节数 - Why is it when I'm downloading my array and try to get the length of it, it just spits out the number of bytes the array is 如何解决“函数作为 React 子级无效”。 当我尝试根据函数的输出渲染组件时出错? - How to solve "Functions are not valid as a React child." error when I try to render a components based on the output of a function? reactjs将对象数组渲染到列表中给出错误 - reactjs render array of objects into a list gives an error 尝试从数据库呈现对象数组时出错 - Error trying to render an array of objects from the database 如何渲染对象数组? - How can I render an array of objects? 当我尝试将新的 object 添加到我的 state 数组中时,它会将所有现有对象更改为新的 object - When I try to add a new object to my state array, it changes all existing objects to the new object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM