Stale props inside a method of a class-based component

This is a spelling game. The user drags the correct letter over the dropzone. On drop, the function checkIfLetterIsCorrect is invoked and runs the checking process. When all dropzones are filled with the correct letter the app moves on to the next word and props and state or in sync.

This all works fine on a hard refresh. However, this component is inside a Semantic UI React modal, and when the modal is closed and reopened, and I set the game back up this.props.currentWordLetters is the correct value, but when checkIfLetterIsCorrect is invoked, the value of this.props.currentWordLetters inside this method is of the value before the modal was closed. I checked with a console.log inside ComponentWillUnmount and the component is indeed unmounting when the modal is closed, so I don’t see why the values inside checkIfLetterIsCorrect would be outdated as everything should be rendered like new. If somebody could point me in the right direction it would be a big help. Thank you.

class DropzoneContainer extends React.Component {
	constructor() {
		super();
		this.state = {
			correctCounter: 0,
		};
	}

	componentWillUnmount(){
		console.log('unMounted')
	}

	checkIfLetterIsCorrect(e) {
		
		for (let i = 0; i < this.props.currentWordLetters.length; i++) {
			console.log(this.props.currentWordLetters, this.state.letters);
			if (
				this.props.currentWordLetters[i] ===
					e.relatedTarget.innerText &&
				e.relatedTarget.innerText === e.target.innerText
			) {
				e.relatedTarget.classList.remove('draggable');
				this.props.onCorrectLetter();
		

				this.setState({
					correctCounter: this.state.correctCounter + 1,
				});
				if (this.state.correctCounter === this.props.currentWordLetters.length) {
					this.setState({ correctCounter: 0 })
					clearInterval(this.props.timer.current);
					this.props.onTimerStop();

					this.props.onRoundComplete();
					return;
				}
			}
		}
	}
//...

Here is the entire component:

import React from 'react';
import { connect } from 'react-redux';
import interact from 'interactjs';
import { Grid } from 'semantic-ui-react';
import Dropzone from '../dropzone/dropzone.component'

import {
	onCorrectLetter,
	onRoundComplete,
	onTimerStop,
} from '../../../../actions/phonicsGameActions';

class DropzoneContainer extends React.Component {
	constructor() {
		super();
		this.state = {
			correctCounter: 0,
		};
	}

	componentWillUnmount(){
		console.log('unMounted')
	}

	checkIfLetterIsCorrect(e) {
		
		for (let i = 0; i < this.props.currentWordLetters.length; i++) {
			console.log(this.props.currentWordLetters, this.state.letters);
			if (
				this.props.currentWordLetters[i] ===
					e.relatedTarget.innerText &&
				e.relatedTarget.innerText === e.target.innerText
			) {
				e.relatedTarget.classList.remove('draggable');
				this.props.onCorrectLetter();
		

				this.setState({
					correctCounter: this.state.correctCounter + 1,
				});
				if (this.state.correctCounter === this.props.currentWordLetters.length) {
					this.setState({ correctCounter: 0 })
					clearInterval(this.props.timer.current);
					this.props.onTimerStop();

					this.props.onRoundComplete();
					return;
				}
			}
		}
	}

	componentDidMount() {

		console.log("component mountedw " + this.props.currentWordLetters)
		// enable draggables to be dropped into this
interact(".inner-dropzone").dropzone({
	// only accept elements matching this CSS selector
	accept: ".draggable",
	// Require a 75% element overlap for a drop to be possible
	overlap: 0.75,
 
	// listen for drop related events:
 
	ondropactivate: function (event) {
	  // add active dropzone feedback
	  event.target.classList.add("drop-active");
	},
	ondragenter: function (event) {
	  var draggableElement = event.relatedTarget;
	  var dropzoneElement = event.target;
 
	  // feedback the possibility of a drop
	  dropzoneElement.classList.add("drop-target");
	  draggableElement.classList.add("can-drop");
	  //draggableElement.textContent = 'Dragged in'
	},
	ondragleave: function (event) {
	  // remove the drop feedback style
 
	  event.target.classList.remove("correct");
	  event.target.classList.remove("incorrect");
	  event.target.classList.remove("drop-target");
	  event.relatedTarget.classList.remove("can-drop");
	  event.target.classList.remove("test");
	  //event.relatedTarget.textContent = 'Dragged out'
	},
	ondrop:  (event)=> {
	  event.stopImmediatePropagation();
	  this.checkIfLetterIsCorrect(event)
 
 
	},
  
	ondropdeactivate: function (event) {
	  // remove active dropzone feedback
	  event.target.classList.remove("drop-active");
	  event.target.classList.remove("drop-target");
	  event.target.classList.remove("drop-target");
	},
 })
	}


	render() {
	
		return (
			<Grid>
				<Grid.Row style={{ justifyContent: 'space-evenly' }}>
					{this.props.currentWordLetters.length > 1
						? this.props.currentWordLetters.map((zone) => (
								<Dropzone
									key={zone}
									letter={zone}
									style={{
										color: 'rgba(0,0,0,0)',
										width: '55px',
										height: '55px',
										border: 'dotted white 2px',
									}}
									className="inner-dropzone"
								/>
						  ))
						: 'Loading Dropzone...'}
				</Grid.Row>
			</Grid>
		);
	}
}



const mapDispatchToProps = (dispatch) => ({
	onRoundComplete: () => dispatch(onRoundComplete()),
	onCorrectLetter: () => dispatch(onCorrectLetter()),
	onTimerStop: () => dispatch(onTimerStop()),
});

const mapStateToProps = (state) => ({
	currentWordLetters: state.phonicsGameReducer.currentWordLetters,
});

export default connect(mapStateToProps, mapDispatchToProps)(DropzoneContainer);

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.