I'm trying to make a react component that would print out the total sum of selected values in 2 ChoiceGroup components. It must evaluate on every choice change. I'm updating state with SetState, but something is not right, as it calculates and shows value correctly, but choice is not being selected on the UI. In other words, I have to double click the choice to work correctly. I think it's related to SetState being asyncronous? I'm complete newbie in react, there must be a better way than making new handlers for each ChoiceGroup?
Here is my code:
import * as React from 'react';
import { ChoiceGroup, IChoiceGroupOption } from 'office-ui-fabric-react/lib/ChoiceGroup';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';
import styles from './ProjectSizingTool.module.scss';
import { IProjectSizingToolProps } from './IProjectSizingToolProps';
import { escape } from '@microsoft/sp-lodash-subset';
export default class ProjectSizingTool extends React.Component<IProjectSizingToolProps, {}> {
state = {
scores: [],
score: 0
}
constructor (props){
super(props);
this.state = {
scores : [0, 0, 0, 0, 0, 0, 0, 0, 0],
score: 0
}
}
public render(): React.ReactElement<IProjectSizingToolProps> {
var score = this.state.score;
return (
<div className={ styles.projectSizingTool }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<ChoiceGroup label='Project Complexity'
options={[
{key: '1', text: 'Well Mastered Routine'},
{key: '3', text: 'Many similar projects done before'},
{key: '5', text: 'Some Experience / High Bid Value'},
{key: '8', text: 'Complex / Bespoke Solution'}
]}
onChange={ this._onChoice1Change } required = {true}
/>
<ChoiceGroup label='Bid Value / Contract'
options={[
{key: '1', text: '0K – £100K / Cost + fee'},
{key: '3', text: '£0K - £100K / Time & Material'},
{key: '5', text: '75K - £1M / Lump Sum'},
{key: '8', text: '£750K + / Lump Sum'}
]}
onChange={ this._onChoice2Change } required = {true}
/>
<a href="#" className={ styles.button }>
<span className={ styles.label } >{score}</span>
</a>
</div>
</div>
</div>
</div>
)
}
private calculateScore(scores) {
let score = 0;
console.log ("scores: " + scores)
for (let i in scores) {
score += parseInt(scores[i]);
}
return score;
}
@autobind
private _onChoice1Change(ev: React.FormEvent<HTMLInputElement>, option: any) {
var tempScores = this.state.scores.slice();
tempScores[0] = option.key;
const newScore = this.calculateScore(tempScores);
this.setState({
score : newScore
});
}
@autobind
private _onChoice2Change(ev: React.FormEvent<HTMLInputElement>, option: any) {
var tempScores = this.state.scores.slice();
tempScores[1] = option.key;
const newScore = this.calculateScore(tempScores);
this.setState({
score : newScore
});
}
}