0

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:

enter image description here

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 of FormControl, 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 this resetSlider 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>
      )
    }
}

Null Salad
  • 765
  • 2
  • 16
  • 31
  • If you include a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) it will be easier for someone to help you! – Tholle Dec 22 '20 at 02:26
  • 1
    updated with an example :) – Null Salad Dec 22 '20 at 02:37
  • 1
    You most likely want to keep your "global state" in the `FormControl` component and pass down the state and state-altering functions to your `QuestionBox` components. React will not pick up on when you mutate global variables. – Tholle Dec 22 '20 at 02:41
  • Are you using any state management library? – kennysliding Dec 22 '20 at 03:41
  • no I'm not, although not for any particular reason. Any recommendations? RE: State in FormControl, this would be ideal but solutions to modify nested states are kinda nasty looking https://stackoverflow.com/questions/43040721/how-to-update-nested-state-properties-in-react . If there's no more elegant solution I will probably just go with this – Null Salad Dec 22 '20 at 04:01

0 Answers0