私は反応を覚えており、このチュートリアルに従う:https://scotch.io/tutorials/build-a-react-flux-app-with-user-authentication私のアプリケーションに認証を追加する。状態が変更された後に反応コンポーネントが再レンダリングされない
悲しいことに、私はログインボタンを更新するだけで、認証されたコンテンツを見るためにブラウザをリフレッシュする必要があることに気付きました。
私はすべての上に検索し、無駄に状態や小道具を設定し、子供たちに親からそれらを渡すが、すべて試してみました。
以下は私の3つのコンポーネントです。何でも大歓迎です。ウェブ全体を見てきました。&は、他のリアクト・アプリケーションを既に研究しています。
ありがとうございました。
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;
お返事ありがとうございます。私のコードは別のファイルにありますが、ここにすべて貼り付けて、何が起きているのかを確認することができます。認証は機能していますが、すべてのコンポーネントで状態を設定してレンダリングする必要があります。現在、ログインボタン自体は認証状態で再レンダリングされます。残りの部分は、リフレッシュ時にのみ認証されます。あなたは、コードを分割するためにあなたに別のファイルと輸入 –
を助け場合、私はあなたのプロジェクトを表示することができます。認証された状態でどのコンポーネントを再レンダリングするか、認証されたときと認証されなかったときの違いは何ですか?コードからは、アプリケーションを見ると、ボタンだけが –
さて、感謝を示すために、私は上記のコードを分割しました –