React中是否有一种特殊的方法可以更新DOM?

时间:2019-07-16 19:47:04

标签: javascript reactjs ecmascript-6

你好,我正在React中制作一个抽认卡应用程序,我试图在两张卡之间进行切换,但是直到我将卡切换过来后,它们才会更新。

我尝试将索引currentCard设置为state而不是global,但是在实现该索引时遇到了一些问题。我也尝试过this.forceUpdate(),但是它们都未定义出来。

import React from 'react';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';

// variables
let currentCard = 0;

这是我从以下位置获得卡片的地方:

const mockData = [
  {
    front: "Hello",
    back: "Dobrý den"
  },
  {
    front: "How are you?",
    back: "Jak se máš?"
  },
  {
    front: "I'm fine",
    back: "Mám se dobře"
  }

];

class LeftArrow extends React.Component {
  constructor(props){
    super(props);
    this.state = {isClicked: false};
  }

  render(){
    //checks it so it can't be less than zero
    return(
      <button
      className="btn btn-primary"
      onClick={() => this.props.onCardChange('LEFT')}
      >&lt;</button>
    )
  }
}

class RightArrow extends React.Component {
  constructor(props){
    super(props);
    this.state = {isClicked: false};
  }

  render(){
    // checks it so it isn't more than the length of array
    // checks if card has
    return(
      <button
      className="btn btn-primary"
      onClick={() => this.props.onCardChange('RIGHT')}
      >
      &gt;
      </button>
    )
  }
}

class Card extends React.Component {
  constructor(props){
    super(props);
    // helps toggle between the front face and the back
    this.state = {
      isFront: true,
    };
  } 

这是当有人单击箭头时我正在使用的方法:

  handleCardChange(direction) {
    if(direction === 'RIGHT'){
      console.log(direction);
      if(currentCard < mockData.length - 1){
        currentCard += 1;
      } else if (currentCard == mockData.length - 1) {
        currentCard = 0;
      }
    }

    if (direction === 'LEFT') {
      if (currentCard > 0) {
        currentCard -= 1;
      } else if (currentCard == 0) {
        currentCard = mockData.length - 1;
      }
    }
  }

  render(){
    // if clicked, isFront changes to the opposite
    // if isFront is true, show front, if not, show back
    console.log(this.state.wasTurned, currentCard);
    return (
      // , wasTurned: !this.state.wasTurned
      <div className="App">
        <div
        className="Card"
        onClick={() => this.setState({
          isFront: !this.state.isFront,
          wasTurned: true
        })}
        >
          {this.state.isFront ? mockData[currentCard].front : mockData[currentCard].back}
        </div>
        <div className="arrow_panel">
          <LeftArrow onCardChange={this.handleCardChange}/><RightArrow onCardChange={this.handleCardChange}/>
        </div>
      </div>
    );
  }
}

export default Card; 

我希望卡会自动更新,因此,当我单击箭头时,它将显示下一张卡的正面/背面,但是您必须再次单击该卡才能看到下一张卡。非常感谢您阅读到这一点,并从忙碌的一天中抽出宝贵的时间来帮助我。

// variables
let currentCard = 0;
const mockData = [
  {
    front: "Hello",
    back: "Dobrý den"
  },
  {
    front: "How are you?",
    back: "Jak se máš?"
  },
  {
    front: "I'm fine",
    back: "Mám se dobře"
  }

];

class LeftArrow extends React.Component {
  constructor(props){
    super(props);
    this.state = {isClicked: false};
  }

  render(){
    //checks it so it can't be less than zero
    return(
      <button
      className="btn btn-primary"
      onClick={() => this.props.onCardChange('LEFT')}
      >&lt;</button>
    )
  }
}

class RightArrow extends React.Component {
  constructor(props){
    super(props);
    this.state = {isClicked: false};
  }

  render(){
    // checks it so it isn't more than the length of array
    // checks if card has
    return(
      <button
      className="btn btn-primary"
      onClick={() => this.props.onCardChange('RIGHT')}
      >
      &gt;
      </button>
    )
  }
}

class Card extends React.Component {
  constructor(props){
    super(props);
    // helps toggle between the front face and the back
    this.state = {
      isFront: true,
    };
  }

  handleCardChange(direction) {
    if(direction === 'RIGHT'){
      console.log(direction);
      if(currentCard < mockData.length - 1){
        currentCard += 1;
      } else if (currentCard == mockData.length - 1) {
        currentCard = 0;
      }
    }

    if (direction === 'LEFT') {
      if (currentCard > 0) {
        currentCard -= 1;
      } else if (currentCard == 0) {
        currentCard = mockData.length - 1;
      }
    }
  }

  render(){
    // if clicked, isFront changes to the opposite
    // if isFront is true, show front, if not, show back
    console.log(this.state.wasTurned, currentCard);
    return (
      // , wasTurned: !this.state.wasTurned
      <div className="App">
        <div
        className="Card"
        onClick={() => this.setState({
          isFront: !this.state.isFront,
          wasTurned: true
        })}
        >
          {this.state.isFront ? mockData[currentCard].front : mockData[currentCard].back}
        </div>
        <div className="arrow_panel">
          <LeftArrow onCardChange={this.handleCardChange}/><RightArrow onCardChange={this.handleCardChange}/>
        </div>
      </div>
    );
  }
}


ReactDOM.render(<Card />, document.getElementById('root'));
.App {
  text-align: center;
}

.Card {
  margin: 0 auto;
  width: 50%;
  padding: 50px;
  border: 1px solid black;
  border-radius: 5px;
  font-size: 40px;
}

.arrow_panel button {
  margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="theme-color" content="#000000" />
  <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
  <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
  <title>React App</title>
</head>

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
  <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
</body>

</html>

2 个答案:

答案 0 :(得分:0)

您必须将模拟数据和currentCard置于Card组件的状态,并且handleCardChange应该用this.setState({})更新该状态。

const mockData = [
  {
    front: "Hello",
    back: "Dobrý den"
  },
  {
    front: "How are you?",
    back: "Jak se máš?"
  },
  {
    front: "I'm fine",
    back: "Mám se dobře"
  }
];

class Card extends React.Component {
  constructor(props) {
    super(props);
    // helps toggle between the front face and the back
    this.state = {
      isFront: true
      currentCard: 0,
      mockData,
    };
  }

答案 1 :(得分:0)

使用setState

this.setState({someState: "someNewState"})