Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions Quiz/src/jsx/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class App extends React.Component {

_handleSubmit() {
if (this.state.index + 1 < this.state.numberOfQuestions) {
this.setState({
this.setState({
index : this.state.index + 1
})
} else {
this.setState({
this.setState({
completed : true
})
}
Expand All @@ -64,24 +64,22 @@ class App extends React.Component {
score: (correctAnswer === selection) ? this.state.score + 1 : this.state.score,
selectionMade:false
})

}


render() {

const quizCompleted = <div>
<h1> Quiz completed ! </h1>
</div>;
const quiz = <div>
<Question
quiz={this.state.quiz}
index={this.state.index} />
<Question question={this.state.quiz[this.state.index].question} />
<Answer
handleRadio = {this._handleRadio}
buttonEnabled = {this.state.buttonEnabled}
selectionMade = {this.state.selectionMade}
options={this.state.quiz[this.state.index].options}
handleRadio = {this._handleRadio}
buttonEnabled = {this.state.buttonEnabled}
selectionMade = {this.state.selectionMade}
options={this.state.quiz[this.state.index].options}
onClickCallback = {this._handleSubmit} />
</div>;
const quizStage = !this.state.completed ? quiz : quizCompleted ;
Expand All @@ -92,10 +90,10 @@ class App extends React.Component {
<div className="questionWrapper" >
{quizStage}
</div>

</div>
)
}
}

export default App;
export default App;
54 changes: 26 additions & 28 deletions Quiz/src/jsx/components/Answer.jsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
import React from "react";

class Answer extends React.Component{
constructor(props) {
super(props);
const Answer = props => (
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where possible, functional components are IMO better because you get an immediate assurance that there is no lifecycle and no state, which makes it easier to reason about contents.

Un-bracketed arrow functions are even better because they are 'point-free', ie there are no internal references, just a return expression. Previously there were 2 points: declare a variable to define the options, then return a block of content which references the options. I prefer this because it's less moving parts to remember – some people dislike it on the grounds it encourages that any logic (ie the options.map) gets put in the content (I don't see a problem with that 🤷‍♂️ ).

<form>
{props.options.map((option,i) => (
<div className={`option${i}`} key={i}>
<input
type="radio"
name='rad'
id={`option_${i}`}
onChange={() => {
props.handleRadio(i)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer using anonymous event handlers in the view and calling function references within that – this avoids the necessity of re-binding class methods elsewhere because we explicitly avoid the this re-binding that comes from event handler assignment. Previously, the parent component's this binding for handleRadio was over-written by the binding here.

}}
/>
<label htmlFor={`option_${i}`}>
{option}
</label>
</div>
))}

}
<input
type="submit"
className='waves-effect waves-light btn-large submit-button visible'
onClick={props.onClickCallback}
disabled={!props.selectionMade}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boolean attribute expressions can be expressed like this – I love it.

/>
</form>
);

render() {

const options = this.props.options.map( (option,i) => {
return <div className={`option${i}`} key={i}>
<input type="radio" name='rad' id={`option_${i}`} onChange={this.props.handleRadio.bind(this, i)} />
<label htmlFor={`option_${i}`} > {option} </label>
</div>
});

return(
<form onSubmit={this.props.onClickCallback}>
{options}
<input
type="submit"
className='waves-effect waves-light btn-large submit-button visible'
onClick={this.props.onClickCallback}
disabled={ this.props.selectionMade ? '' : 'disabled'} />
</form>
)
}
}


export default Answer;
export default Answer;
19 changes: 7 additions & 12 deletions Quiz/src/jsx/components/Question.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import React from "react";

const Question = (props) =>{

const QuestionObejct = props.quiz[props.index];

return(
<div className="questionWrapper" >
<div className='questions'>
{QuestionObejct.question}
</div>
const Question = ({question}) => (
<div className="questionWrapper" >
<div className='questions'>
{question}
</div>
)
}
</div>
);


export default Question;
export default Question;