Reputation: 1099
I have a simple game app I'm trying to put together as an exercise:
Button
s for selection (i.e. choose all correct answers)Timer.timeRemaining
by N seconds, else decrease Timer.timeRemaining
by M seconds.I thought it seemed easy enough, but in step 1 when I change the button properties (which you can see are an object mapped to each button name/id, maybe not the way to do this?) it does not update the props of Button
so I don't get a re-render.
Is there a standard way that I should be doing this? Prefer to try to do it in React without resorting to Redux yet (if that was an option) since I haven't really learned it (although it is coming up in the book I'm reading through, so if that's necessary to maintain state of the whole game here...).
Relevant part of the code:
ButtonProp class:
class ButtonProp {
constructor(selected = false, style = { backgroundColor: '#1051c5', color: '#fff' }) {
this.isSelected = selected;
this.hasStyle = style;
this.unselectedStyle = {
backgroundColor: '#1051c5',
color: '#fff'
};
this.selectedStyle = {
backgroundColor: '#c1ecff',
color: '#999'
};
}
toggle() {
[this.isSelected, this.hasStyle] = this.isSelected
? [false, this.unselectedStyle]
: [true, this.selectedStyle];
}
}
The class that makes the actual game (called by a separate class called TestGame
, which passes the props, which look like ['A', 'B', 'C', 'D', 'E']
):
class TestGameMaker extends Component {
constructor(props) {
super(props);
let buttonMapArray = [];
props.choices.map((choice) => {
buttonMapArray = [...buttonMapArray, [choice, new ButtonProp()]];
});
const buttonMap = new Map(buttonMapArray);
this.interval = 0;
this.state = {
buttons: buttonMap,
timeRemaining: 10
};
this.selectHandler = this.selectHandler.bind(this);
}
submitHandler(e) {
// Check if the currentSelection array matches the answer
}
selectHandler(e) {
// change the color/background color of the selected button
// toggle currentSelection array entry to true/false
this.state.buttons.get(e.target.id).toggle();
};
render() {
return (
<div>
<Timer timerValue={this.state.timeRemaining} />
{this.props.choices.map(
choice => (
<Button
key={choice.id}
name={choice}
style={this.state.buttons.get(choice).hasStyle}
handler={this.selectHandler}
/>
)
)}
<Submit handler={this.submitHandler} />
</div>
);
}
}
TestGameMaker.propTypes = {
choices: PropTypes.arrayOf(PropTypes.string).isRequired
};
Upvotes: 2
Views: 62
Reputation: 6427
You're pretty far off from how react is meant to work. It looks like you're trying to closely follow OOP principles, but React is much more of a functional framework.
That toggle
method ought to exist on the TestGameMaker
component. It ought to modify the state of that component using setState
. The button component ought to pull it's props from the TestGameMaker
state.
I would recommend going through one of the simple react ToDo
tutorials and pay special attention to the purpose of the component state.
Upvotes: 1