javascript - react this.setState 问题

标签 javascript json reactjs

我正在开发一个 React 应用程序。我正在获取 json 数据并通过随机化数组内的数据进行排序。每当我使用 this.setState 时,状态都会被更新,并且也会更改 json 数据的初始顺序。问题是如何在不干扰 JSON 数据的情况下更新状态?这是我的代码(如果有帮助的话):

import React, { Component } from "react";
import "./App.css";
import { test } from "./test.json";
import swal from 'sweetalert';
import { BrowserRouter, Route, Link } from "react-router-dom";
import Nav from "./Nav";

class App extends Component {
  constructor() {
    super();
    this.state = { index: 0, result: 0, testLength: test.length, test: test };
    let result = 1;
  }

  getTest() {
    return this.state.test
      .sort((a, b) => {
        return 0.5 - Math.random();
      })
      .map((item, i) => {
        if (i == 0) {
          return (
            <section key={i} className="d-flex main-sec">
              <h3>{item.question}</h3>
              <form className="list-group form">
                {item.answer
                  .sort((a, b) => {
                    return 0.5 - Math.random();
                  })
                  .map((item, i) => {
                    return (
                      <li key={i} className="list-group-item test-list list-group-item-action">
                        <input
                          type="radio"
                          name="answer"
                          value={item.isTrue}
                          onClick={this.onChange.bind(this)}
                        />
                        <p>{item.ans}</p>
                      </li>
                    );
                  })}
              </form>
              <button className="pre-button btn btn-lg btn-danger" onClick={this.prevEl.bind(this)}>
                <i className="fa fa-long-arrow-left" aria-hidden="true"/> Prev
              </button>
              <button className="next-button btn btn-lg btn-success" onClick={this.nextEl.bind(this)}>
                Next <i className="fa fa-long-arrow-right" aria-hidden="true" />
              </button>
            </section>
          );
        } else if(i == this.state.testLength - 1) {
            return (
              <section key={i} className="d-none">
              <h3>{item.question}</h3>
              <form className="list-group form">
                {item.answer
                  .sort((a, b) => {
                    return 0.5 - Math.random();
                  })
                  .map((item, i) => {
                    return (
                      <li key={i} className="list-group-item test-list list-group-item-action">
                        <input
                          type="radio"
                          name="answer"
                          value={item.isTrue}
                          onClick={this.onChange.bind(this)}
                        />
                        <p>{item.ans}</p>
                      </li>
                    );
                  })}
              </form>
              <button className="pre-button btn btn-lg btn-danger" onClick={this.prevEl.bind(this)}>
                <i className="fa fa-long-arrow-left" aria-hidden="true"/> Prev
              </button>
              <div id="check-result">
                <button className="pre-button btn btn-lg btn-success" onClick={this.prevEl.bind(this)}>
                  Check Your Result
                </button>
              </div>
            </section>
            )
        }else {
          return (
            <section key={i} className="d-none">
              <h3>{item.question}</h3>
              <form className="list-group form">
                {item.answer.map((item, i) => {
                  return (
                    <li key={i} className="list-group-item test-list list-group-item-action">
                      <input
                        type="radio"
                        name="answer"
                        value={item.isTrue}
                        onClick={this.onChange.bind(this)}
                      />
                      <p>{item.ans}</p>
                    </li>
                  );
                })}
              </form>
              <button className="pre-button btn btn-lg btn-danger" onClick={this.prevEl.bind(this)}><i className="fa fa-long-arrow-left" aria-hidden="true" /> Prev</button>
              <button className="pre-button btn btn-lg btn-success" onClick={this.nextEl.bind(this)}>Next <i className="fa fa-long-arrow-right" aria-hidden="true" /></button>
            </section>
          );
        }
      });
  }

  onChange(e) {
    const currEl = e.target.parentElement.parentElement;
    const result = document.getElementById("result");
    currEl.querySelectorAll("input").forEach(item => {
      return item.setAttribute("disabled", true);
    });
    const currElclicked = e.target.value;

    if (currElclicked == "true") {
      e.target.parentElement.className = "list-group-item test-list list-group-item-action right";
      console.log(result.textContent);
      result.innerHTML = parseInt(result.textContent) + 1;
    } else {
      e.target.parentElement.className = "list-group-item test-list list-group-item-action wrong";
      currEl.querySelectorAll("input").forEach(item => {
        if (item.value == "true") {
          item.parentElement.className = "list-group-item test-list list-group-item-action right";
        }
      });
    }
  }

  prevEl(e) {
    const currEl = e.target.parentElement;
    const preEl = e.target.parentElement.previousSibling;
    if (preEl && preEl.nodeName === "SECTION") {
      currEl.className = "d-none";
      preEl.className = "d-flex main-sec";
    } else {
      return;
    }
  }

  nextEl(e) {
    const currEl = e.target.parentElement;
    const nextEl = e.target.parentElement.nextSibling;
    const currElForm = currEl.querySelectorAll("form");
    const isChecked = currElForm[0].querySelectorAll("input:checked");
    console.log(isChecked)
    console.log(this.result)
    if (isChecked.length != 0) {
      if (nextEl && nextEl.nodeName === "SECTION") {
        currEl.className = "d-none";
        nextEl.className = "d-flex main-sec";
        this.setState({index: this.state.index+1})
      } else {
        console.log("wrong");
        return;
      }
    } else {
      swal("To'xtang!", "Javoblardan birini tanlang", "error");
      return;
    }
  }
  render() {
    let result = 0;
    return (
      <div className="App">
        <h1><span id="result">
          {result}</span>
        </h1>
        {this.getTest()}
      </div>
    );
  }
}

export default App;

最佳答案

如果您不希望重新渲染时有新的顺序,请不要在 render 中执行随机排序。

而是在最初收到 json 数据时对其进行排序。

关于javascript - react this.setState 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50279637/

相关文章:

javascript - 使用 Javascript 呈现 HTML 的策略

javascript - TinyMCE 4-如何在将自身粘贴到文本编辑器上时允许某些样式?

javascript - 虚拟机上的跨浏览器测试 - 问题?

java - 日期格式映射到 JSON Jackson

javascript - React Js 中的数据检索和分配

javascript - 将异常信息从主进程返回到渲染进程的正确方法

javascript - 将 Div 的大小设置为与其子项相同(在子项加载之前)

python - 如何从python中的JSON文件中选择数据?

json - 使用youtube api和curl获取所有 channel 信息

javascript - 客户端路由(使用 react-router)和服务端路由