我正在學習反應,並遵循本教程:https://scotch.io/tutorials/build-a-react-flux-app-with-user-authentication向我的應用添加身份驗證。React組件在狀態更改後不重新渲染
完成之後可悲的是,我意識到它僅更新登錄按鈕,你必須刷新瀏覽器中看到的認證內容。
我已經找遍了,並試圖設置狀態和道具,並通過他們從父母到孩子,但都無濟於事。
下面是我的三個組成部分,大規模讚賞任何幫助,我看過所有網站上&研究相互反應Apps中已。
謝謝。
App.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;
SlotMachine.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&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;
PlayButton.js
'use strict';
import React, {Component} from 'react';
import AuthStore from '../stores/AuthStore';
// Creates Spin Button
class PlayButton extends Component {
constructor() {
super();
this.state = {
authenticated: AuthStore.isAuthenticated()
}
}
render() {
//console.log(this, this.props, this.state.authenticated);
return (
<div>
{!this.state.authenticated ? (
<div className="medium-4 small-12">
<button id="play-button" className="play-button" onClick={this.props.login.bind(this)}>Play!</button>
</div>
) : (
<div className="medium-4 small-12">
<button id="play-button" className="play-button" onClick={this.props.logout.bind(this)}>Log out!</button>
</div>
)}
</div>
);
}
}
export default PlayButton;
感謝您的回覆。我的代碼位於不同的文件中,但我將它粘貼在這裏,以便您可以看到發生了什麼。身份驗證正在工作,但我需要在所有組件上設置狀態並讓它們呈現,目前只有登錄按鈕本身會在其已驗證狀態下重新呈現。其餘的只顯示在referesh認證。我可以告訴你這個項目,如果你有幫助 –
我已經分開了上面的代碼來顯示不同的文件和導入 –
好的,謝謝分割代碼。你想在認證狀態下重新呈現哪些組件,它們何時經過身份驗證和何時未經身份驗證有什麼區別。從代碼中,我可以看到,如果你看App,只有按鈕改變 –