反应this.setState问题

时间:2018-05-10 18:48:57

标签: 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;

1 个答案:

答案 0 :(得分:1)

如果您在重新渲染时不想要新订单,请不要在render中执行随机排序。

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