在状态更改后,React组件不会重新呈现

时间:2016-11-10 18:19:46

标签: javascript reactjs oauth react-jsx

我正在学习反应并遵循本教程:https://scotch.io/tutorials/build-a-react-flux-app-with-user-authentication为我的应用添加身份验证。

遗憾的是,在完成它之后,我意识到它只更新了登录按钮,你必须刷新浏览器才能看到经过验证的内容。

我已经搜遍过所有并尝试设置状态和道具并将它们从父母传递给孩子,但都无济于事。

以下是我的三个组成部分,任何帮助都非常受欢迎,我已经浏览了整个网络&已经研究过其他React Apps。

感谢。

App.js

df[,1:2] <- do.call(rbind, strsplit(df$Venue, split = "\\s+(?=\\d)", perl = TRUE))
colnames(df) <- c('Location', 'Year')

SlotMachine.js

import 'normalize.css/normalize.css';
import 'bootstrap/dist/css/bootstrap.min.css';

import React, { Component } from 'react';
import PlayButton from './PlayButton';
import SlotMachine from './SlotMachine';

import AuthActions from '../actions/AuthActions';
import AuthStore from '../stores/AuthStore';



class AppComponent extends Component {



    componentWillMount() {
        this.lock = new Auth0Lock('3RhBq3qZaZARDQae7PtbH59wyP9xe7Ld', 'wolftiger.eu.auth0.com');
    }

    constructor(props) {
        super(props);
        this.state = {
            authenticated: AuthStore.isAuthenticated()
        }
    }


    login() {
        // We can call the show method from Auth0Lock,
        // which is passed down as a prop, to allow
        // the user to log in
        //console.log("parent login", this.props);
        this.props.lock.show((err,profile,token) => {
            if (err) {
                alert(err);
                //console.log(err);
                return;

            }
            AuthActions.logUserIn(profile, token);
            //this.props.login();
            this.setState({authenticated:true});
        });
    }

    logout() {
        AuthActions.logUserOut();
        //this.props.logout();
        this.setState({authenticated:false});
    }

    render() {
        console.log(this, this.props, this.props.children, this.state);
        return (
          <div>
            <div className="container">
                <div className="row">
                    <div className="medium-12 small-12">
                        <h1>Spin and Win</h1>

                        { !this.state.authenticated ? (
                        <div className="medium-12 small-12">
                            <img src="http://placehold.it/960x360"/>
                        </div>
                        ) : (
                            <SlotMachine state={this.state} props={this.props} >
                            </SlotMachine>
                        )}
                    </div>
                </div>
                <div className="row">
                    <div className="medium-12 small-12">
                        <PlayButton
                            lock={this.lock}
                            state={this.state}
                            login={this.login}
                            logout={this.logout}
                        >
                        </PlayButton>
                    </div>
                </div>
            </div>
          </div>
        );
  }
}

//AppComponent.defaultProps = {};


export default AppComponent;

PlayButton.js

'use strict';

import React            from 'react';
import Slots            from './Slots';
import SpinButton       from './SpinButton';
import StatusMessage    from './StatusMessage';
import Chances    from './Chances';

const propTypes = {
  currentUser: React.PropTypes.object
};


// The SlotMachine React class handles the entirety of this very small app.
class SlotMachine extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      slotPositions: this.getRandomState(),
      chancesLeft: 3//this value must be stored in the db

    };
    //console.log(this.state.slotPositions);
  }

  // Generates random initial state for slots.
  componentWillMount() {

  }



  //getInitialState() {
  //  return {slotPositions: this.getRandomState()};
  //}

  genSlotValue(){
    return Math.floor(Math.random() * 3);
  }

  // Generates random landing values for slots using genSlotValue defined at the end of the file
  getRandomState() {
    //console.log(genSlotValue(), genSlotValue(), genSlotValue());
    return [
      genSlotValue(),
      genSlotValue(),
      genSlotValue()
    ];
  }

  useChance() {
      var noOfChances = this.state.chancesLeft;
      this.setState({chancesLeft: minusOne(noOfChances)})
  }

  componentWillReceiveProps() {
    //console.log('componentWillReceiveProps');
    //ReactDOM.render(newProps);
  }

  handleButtonClick(event) {
    //console.log(event, this, this.state);
    this.useChance();
    console.log(event, this, this.state, this.props);
    event.preventDefault();
    // Set count to 0 before each button press
    let count = 0;
    // Set a random state as the final state of all slots before we start spinning
    let finalState = this.getRandomState();
    // Make sure we start with a fresh state for all slots on each spin
    let currentState = this.getRandomState();
    //console.log(currentState,finalState)
    // Spinning happens here
    var makeSpin = function(){
      let nextState = currentState;
      let hasChanged = false;
      var spinButton = document.getElementById('spin-button');

      // Evaluate whether or not slots are on their final destination, spin to nextState if not
      for(var i = 0; i < 3; i++){
        if (count < 9 || currentState[i] != finalState[i]) {

          nextState[i] = (currentState[i]+1)%3;
          hasChanged = true;
          spinButton.setAttribute('disabled', 'disabled');
          //spinButton.setTextContent('Spinning!');
          spinButton.classList.add('spinning');
        }
        //Re-enable spin button
        if (count >= 9){
          //console.log('count more than 9')
          spinButton.removeAttribute('disabled');
          //  spinButton.setTextContent('Spin!');
          spinButton.classList.remove('spinning');
        }
      }

      // Moves reel to the next assigned state if it's not yet on it's final value.
      this.setState({slotPositions: nextState, isFinal: !hasChanged})

      // Stops reel spinning if we've hit the final state's value
      if(!hasChanged) {
        return;
      }
      currentState = this.state.slotPositions;
      setTimeout(makeSpin, 100);
      count++;
      //console.log(count);
    }.bind(this);


    // Actually spin
    makeSpin();
  }




  render() {

      // Define winning states
      let sp = this.state.slotPositions;
      let isWinning = (sp[0] == sp[1]) && (sp[1] == sp[2]);

      // Make sure winner, winnerClass, and winnerImage strings are undefined until there's an actual win
      let winner = '';
      let winnerClass = '';
      let winnerImage = '';

      // Make sure we're only displaying the win state on final slot positions
      if(isWinning && this.state.isFinal){
        winner = [
          <h2>You've won John Lewis vouchers!</h2>,
          <h2>You've won M&amp;S vouchers!</h2>,
          <h2>You've won Size vouchers!!</h2>
        ][sp[0]];
        winnerClass = [
          'coffee',
          'tea',
          'espresso'
        ][sp[0]];
        winnerImage = [
          <div id='coffee-img' className='tossing win-img'></div>,
          <div id='tea-img' className='tossing win-img'></div>,
          <div id='espresso-img' className='tossing win-img'></div>
        ][sp[0]];
    }

    //console.log(this, this.props, this.props.state.authenticated);
    return (
      <main className='react-slots'>
        <div className="medium-12 small-12">
          <Chances chancesLeft={this.state.chancesLeft}  />
          <section className="machine">
            <Slots slotPositions={this.state.slotPositions} />
            <div className="spin row">
              <SpinButton onButtonClick={this.handleButtonClick.bind(this)} />
            </div>
          </section>
          <section className="win row">
            <StatusMessage winner={winner} winnerClass={winnerClass} winnerImage={winnerImage} />
          </section>
        </div>
      </main>
    );
  }

}

// Generates a random slot value.
function genSlotValue(){
  return Math.floor(Math.random() * 3);
}

function minusOne(value){
  return value - 1;
}



SlotMachine.propTypes = propTypes;


export default SlotMachine;

3 个答案:

答案 0 :(得分:0)

首先,您没有导入function serachForKeyword($keyword) { $db = getDbConnection(); $stmt = $db->prepare("SELECT title,id,slug FROM `articles` WHERE title LIKE ? ORDER BY title ASC"); $keyword = $keyword . '%'; $stmt->bindParam(1, $keyword, PDO::PARAM_STR, 100); $isQueryOk = $stmt->execute(); $results = array(); if ($isQueryOk) { $results = $stmt->fetchAll(PDO::FETCH_COLUMN); } else { trigger_error('Error executing statement.', E_USER_ERROR); } $db = null; return $results; AuthStore。同样,AuthActions作为道具传递到lock的位置。在AppComponent之前,您必须确保道具中有锁定。如果您可以将代码重组为不同的文件,那么可以更容易地弄清楚发生了什么。在教程中,this.props.lock作为道具传递到this.lock组件,然后在标题组件中调用Header,在您自己的情况下,您可能应该{{1}在this.props.lock.show方法中而不是this.lock.show

答案 1 :(得分:0)

您应该包含SlotMachine,而不是<SlotMachine state={this.state} props={this.props} />,而不是<SlotMachine state={this.state} props={this.props} ></SlotMachine>,因为后者假定它内部会有儿童组件/元素。你也应该重命名你传递给它的道具。写this.props.props

肯定会让人感到困惑

答案 2 :(得分:0)

我最终通过配置react-router并以这种方式加载新组件来解决这个问题,这迫使新加载的组件检查身份验证并显示相应的内容。

我的应用实际上并不需要路由,因为它嵌入在页面中,我仍然希望找到一个没有路由的解决方案,但现在已经足够了。