0

I have a front-end in react-mui with a list of 8 words and each word has its state updated based on its input and it may also be disabled. Example:

        <TextField required id="standard-basic" disabled={this.state.word1Disabled} label="Word1" value={this.state.word1} onChange={(event) => this.setState({word1:event.target.value.trim()})} />
        <TextField required id="standard-basic" disabled={this.state.word2Disabled} label="Word2" value={this.state.word2} onChange={(event) => this.setState({word2:event.target.value.trim()})} />

The user can decide which of the 8 words to disable using a dropdown menu which implements the following function:

    const handleWord = event => {

    switch(event.target.value) {
        case "1":
          this.setState({word1Disabled:true,word2Disabled:false,word3Disabled:false,word4Disabled:false,word5Disabled:false,word6Disabled:false,word7Disabled:false,
            word8Disabled:false})
          break;
        case "2":
            this.setState({word1Disabled:false,word2Disabled:true,word3Disabled:false,word4Disabled:false,word5Disabled:false,word6Disabled:false,word7Disabled:false,
                word8Disabled:false})
          break;
        case "3":
            this.setState({word1Disabled:false,word2Disabled:false,word3Disabled:true,word4Disabled:false,word5Disabled:false,word6Disabled:false,word7Disabled:false,
                word8Disabled:false})
          break;
        case "4":
            this.setState({word1Disabled:false,word2Disabled:false,word3Disabled:false,word4Disabled:true,word5Disabled:false,word6Disabled:false,word7Disabled:false,
                word8Disabled:false})
          break;
        case "5":
            this.setState({word1Disabled:false,word2Disabled:false,word3Disabled:false,word4Disabled:false,word5Disabled:true,word6Disabled:false,word7Disabled:false,
                word8Disabled:false})
          break;
        case "6":
            this.setState({word1Disabled:false,word2Disabled:false,word3Disabled:false,word4Disabled:false,word5Disabled:false,word6Disabled:true,word7Disabled:false,
                word8Disabled:false})
          break;
        case "7":
            this.setState({word1Disabled:false,word2Disabled:false,word3Disabled:false,word4Disabled:false,word5Disabled:false,word6Disabled:false,word7Disabled:true,
                word8Disabled:false})
          break;
        case "8":
            this.setState({word1Disabled:false,word2Disabled:false,word3Disabled:false,word4Disabled:false,word5Disabled:false,word6Disabled:false,word7Disabled:false,
                word8Disabled:true})
          break;

      }

     }

While the above solution solves my problem, I assume it's not good programming practice because it's over repetitive. Could someone confirm if I am on the right track?

Now I want to give the user the ability to disable two words at the same time using the dropdown menu, say word 1 and 2. How can I modify the handleWord function to achieve such? I tried to think about it but the way I think it is becoming even more repetitive, handling EVERY possible case for each of the two words disabled (8x8 = 64 cases lol).

The desired outcome is that the user will be able to pick two words they want to disable and those textfields receive the "disabled={true}" property. If the user changes their mind and want to change the word, then the old disabled textfield becomes enabled again.

5
  • To get round the repetitiveness, you need to think about it slightly differently e.g. you can combine the entire logic into on line by doing something like this.setState({word1Disabled: event.target.value === "1", word2Disabled: event.target.value === "2"...etc...etc). Personally, I would not use conditional logic the that to act on the value because like you have noticed, you will have to keep adding a tiny bit more code -> Commented Apr 15, 2020 at 19:09
  • 1
    I would just push the value into array and set that into state and then you check if it is disabled by doing something something disabledWords.includes(myValue) so then the handler wouldn't need to be modified if more words are added Commented Apr 15, 2020 at 19:10
  • @Tom Finney good idea about combining the entire logic. I am still trying to understand what exactly you mean in the second comment. Do you mean pushing all word values in an array and then remove them when "disabled"? Commented Apr 15, 2020 at 19:23
  • @Drew Reese I am looking now for both words to be disabled at the same time. Commented Apr 15, 2020 at 19:23
  • 1
    Yeah, exactly something like that. If you think about using an array to store references to what is disabled, you can essentially remove all that code you wrote. I threw together this quick code sandbox to demonstrate it: codesandbox.io/s/musing-hofstadter-cg67i Commented Apr 15, 2020 at 19:34

1 Answer 1

1

You can use the following line of code for your 8x8 = 64 cases :)

this.setState({['word' + event.target.value + 'Disabled']: true});

For Disabling by multiple input:

"1,3,5".split(',').map(value => {
            this.setState({['word' + value + 'Disabled']: true});
        });

Here is the complete Example:

import React, {Component} from "react";
export class WordsDisable extends Component {
    state = {
            word1Disabled: false,
            word2Disabled: false,
            word3Disabled: false,
            word4Disabled: false,
            word5Disabled: false,
            word6Disabled: false,
            word7Disabled: false,
            word8Disabled: false
        };

    handleWord= (event) => {
        // Setting false for all words
        this.setState({
            word1Disabled: false,
            word2Disabled: false,
            word3Disabled: false,
            word4Disabled: false,
            word5Disabled: false,
            word6Disabled: false,
            word7Disabled: false,
            word8Disabled: false
        });

        this.setState({['word' + event.target.value + 'Disabled']: true});
    };
    render() {
        return (
            <div>
                <ul>
                    <input onChange={this.handleWord}/>
                </ul>
            </div>
        )
    }
}

Last but not the least, You dont need to update all property using setState. You just update your single property and rest will keep the previous value. For example:

switch (event.target.value) {
    case "1":
        this.setState({word1Disabled: true});
        break;
    case "2":
        this.setState({word2Disabled: true});
        break;
    case "3":
        this.setState({word3Disabled: true});
        break;
    case "4":
        this.setState({word4Disabled: true});
        break;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Almost. Trying to apply it to the case where you have two inputs that disable two words at the same time. Yours works very well for one input however.
Hi, @Sophie259, I have added one more example in my answer. I tested it. It works for multiple input. can you please check that?
Fantastic :) I was using Tom's code sanbox and was iterating over an array but the mapping part is good idea as well.
Thanks for your appreciation :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.