Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there any cleaner way to make this amount of comparations in an if clause?

if (this.state.height !== prevState.height || this.state.hair !== prevState.hair || this.state.weight !== prevState.weight || this.state.eyes !== prevState.eyes || this.state.activity !== prevState.activity || this.state.gender !== prevState.gender || this.state.age !== prevState.age || this.state.wage !== prevState.wage || this.state.city !== prevState.city || this.state.disability !== prevState.disability) {
      this.setState({
        person: {
          height: this.state.height, hair: this.state.hair, weight: this.state.weight, city: this.state.city, eyes: this.state.eyes, disability: this.state.disability,
        },
      });
      this.setState({ showSave: this.state.height.length > 0 && this.state.hair.length > 0 && this.state.activity.length > 0 && this.state.gender.length > 0 && this.state.age.length > 0 && this.state.wage.length > 0 && this.state.overtime.length > 0 && this.state.allowance.length > 0 });
    }

What I’m doing is saving the state of a form, the state person has the fields that are set above whenever one of them change, and the state showSave depends of some of those fields and some others, which is also updated if any of the above fields change.
Also, the state of the class has more fields that are not needed in this if.

I’m looking for a cleaner / easier to read way of making all these comparations without needing to add all of this.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

/**
* Factory function to define which properties in state you want to compare
* @param {string[]} keys the keys in state you want to compare
* @returns {(state, prevState) => boolean} function to compare state instances
*/
const makeCompareState = (keys) => {
  /**
  * @param {state} current state instance
  * @param {prevState} previous state instance
  * @returns {boolean} true if properties in state are unchanged, false otherwise
  */
  const compareState = (state, prevState) => {
    return keys.every(key => state[key] === prevState[key])
  }

  return compareState;
};


// Define the keys of state you want to compare
const compareState = makeCompareState(["height", "weight", "hair", "city"])

if(compareState(state, prevState) {
 // state has not changed
} else {
 // state has changed
}

Note, this solution only works for primitive value since it does a shallow comparison, ie. this will not work for comparing objects, functions, or arrays.

Alternatively, you can use a third-party solution if you don’t mind the extra bundle size, like dequal, to do a deep comparison of state

import { isEqual } from "dequal";

if(isEqual(state, prevState)) {
  // state is unchanged
} else {
  // state has changed
}

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading