javascript - React components not re-rendering after state changes -
i learning react , followed tutorial: https://scotch.io/tutorials/build-a-react-flux-app-with-user-authentication add authentication app.
sadly after completing realised updates login button , have refresh browser see authenticated content.
i've searched on , tried setting state , props , passing them parent children no avail.
below 3 components, massively appreciated, i've looked on web & studied other react apps already.
thanks.
app.js
import 'normalize.css/normalize.css'; import 'bootstrap/dist/css/bootstrap.min.css'; import react, { component } 'react'; import playbutton './playbutton'; import slotmachine './slotmachine'; import authactions '../actions/authactions'; import authstore '../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() { // can call show method auth0lock, // passed down prop, allow // user 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 , 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 'react'; import slots './slots'; import spinbutton './spinbutton'; import statusmessage './statusmessage'; import chances './chances'; const proptypes = { currentuser: react.proptypes.object }; // slotmachine react class handles entirety of small app. class slotmachine extends react.component { constructor(props) { super(props); this.state = { slotpositions: this.getrandomstate(), chancesleft: 3//this value must stored in db }; //console.log(this.state.slotpositions); } // generates random initial state slots. componentwillmount() { } //getinitialstate() { // return {slotpositions: this.getrandomstate()}; //} genslotvalue(){ return math.floor(math.random() * 3); } // generates random landing values slots using genslotvalue defined @ end of 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 0 before each button press let count = 0; // set random state final state of slots before start spinning let finalstate = this.getrandomstate(); // make sure start fresh state 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 on final destination, spin nextstate if not for(var = 0; < 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 9') spinbutton.removeattribute('disabled'); // spinbutton.settextcontent('spin!'); spinbutton.classlist.remove('spinning'); } } // moves reel 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 final state's value if(!haschanged) { return; } currentstate = this.state.slotpositions; settimeout(makespin, 100); count++; //console.log(count); }.bind(this); // 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, , winnerimage strings undefined until there's actual win let winner = ''; let winnerclass = ''; let winnerimage = ''; // make sure we're displaying 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 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} 'react'; import authstore '../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;
first of all, not importing authstore , authactions. lock being passed props appcomponent. have make sure lock available in props before can this.props.lock. easier figure out going on if can restructure code different files. tutorial, this.lock passed props header component, , this.props.lock.show called in header component, in own case should this.lock.showinside login method instead of this.props.lock.show
Comments
Post a Comment