I have a form with many different sliders. I want to press a button, and have all the sliders reset to their default value. My current architecture is like this:
My solution is to use a global variable,
let surveyParams = {
"block1":{
"enjoyment":3,
"stress":3,
//...
},
"block2":{
"sliderDescription1":3,
"sliderDescription2":3,
//...
}
}
}
This global variable is the "state" of each slider. SubmitButton will call a function that will reset the global variable. However, it appears that the sliders possibly(?) keep a local version of surveyParams
. When I access surveyParams
from SubmitButton
it is unaffected.
Am I using the wrong architecture here or method of approach? I find it is hard to get out of Objected Oriented Brain, and into a declarative mindset.
The methods I have tried, and why they are inadequate:
- I tried treating
surveyParams
as a state ofFormControl
, but this doesn't work because it has "nested state" that I cannot easily modify. It would be inadequate to flatten the hierarchy because the page dynamically generates sliders based off the JSON file structure. - I tried keeping the state local to each slider, and having a
resetSlider()
function inside of the slider class component. However, I would need to pass thisresetSlider
function to a child submit button, and that would entail having one submit button for every slider, and I only want one submit button for all sliders.
So my question is this:
What is the best way to architect this so that a single submit button can reset the values of all the sliders to default?
EDIT: here is a minimal version of my code:
// Global variable, this is what StyledSlider uses as "state"
let surveyParams = {
"block1": {
"enjoyment": 3,
"stress": 3,
// ...
},
"block2": {
"Openess": 3,
"Conscientiousness":3,
// ...
}
}
// global scope reset values function
let resetValues = function(objToReset){
console.log("reset values called")
// resets values of all keys to 3
Object.keys(objToReset).map((key, indx) => {
objToReset[key] = 3;
})
}
// Big parent class
class FormControl extends Component{
constructor(props){
super(props);
}
updateBlock1(value){
console.log("the value is: ",value);
surveyParams.block1[value[0]] = value[1];
console.log(surveyParams)
}
updateBlock2(value) {
console.log("the value is: ", value);
surveyParams.block2[value[0]] = value[1];
console.log(surveyParams)
}
render(){
return (
<div className="App">
<QuestionBox
words={surveyParams.block1}
updateValue={this.updateEmoValue}
subsetName={"block1"}
/>
<p/>
<b>Personality questions</b><br/>
<QuestionBox
words={surveyParams.personality}
updateValue={this.updatePersonValue}
subsetName={"block2"}
/>
{/* would like to reset values from a button, as seen here */}
<button onClick={e => resetValues()}> submit </button>
</div>
);
}
}
// Generates a bunch of sliders based off the keys of surveyParams
function QuestionBox(props){
return(
<table>
{Object.keys(props.words).map((key, index) =>
// console.log(props.words[key], key, index);
<tr className="parentTable">
<td>
<span className="emph">{key}</span>
</td>
<td>
<SliderStyled updateValue={props.updateValue}
keyRef={key}
subsetName={props.subsetName}/>
</td>
</tr>
)}
</table>
)
}
// The slider class for which I would like to clear the value of
class SliderStyled extends Component{
constructor(props){
super(props);
this.handleChange = this.handleChange.bind(this);
this.resetSlider = this.resetSlider.bind(this);
}
handleChange(e,value){
console.log("handling change",value)
this.setState({internalValue:value});
surveyParams[this.props.subsetName][this.props.keyRef] = value
console.log("survey params: ",surveyParams)
}
resetSlider(){
this.setState({internalValue:3})
}
render(){
return(
<div className="sliderSection">
<ThemeProvider theme={muiTheme}>
<div className="spectrumLabelContainer">
<div className="leftSpectrum">Strong mismatch</div>
<div className="rightSpectrum">Strong match</div>
</div>
<Slider
value={surveyParams[this.props.subsetName][this.props.keyRef]}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
step={1}
marks
min={1}
max={5}
onChange={this.handleChange}
onChangeCommitted={
(event, newValue)=>{
console.log("hi", this.props.subsetName)
}
}
/>
</ThemeProvider>
</div>
)
}
}