Trouble understanding Pomodoro Clock react logic

I’m currently going through the Pomodoro Clock project using React and am having a hard time understanding the syntax and logic behind large parts of code that others have written. For instance, in the following code from the freecodecamp example at https://codepen.io/freeCodeCamp/pen/XpKrrW?editors=0110

lengthControl(stateToChange, sign, currentLength, timerType) {
    if (this.state.timerState == 'running') return;
    if (this.state.timerType == timerType) {
      if (sign == "-" && currentLength != 1 ) {
        this.setState({[stateToChange]: currentLength - 1});
      } else if (sign == "+" && currentLength != 60) {
        this.setState({[stateToChange]: currentLength + 1});
      } 
    } else {
      if (sign == "-" && currentLength != 1 ) {
        this.setState({[stateToChange]: currentLength - 1,
        timer: currentLength * 60 - 60});
      } else if (sign == "+" && currentLength != 60) {
        this.setState({[stateToChange]: currentLength + 1,
        timer: currentLength * 60 + 60});
      } 
    }
  }

I can’t understand why the lengthcontrol method takes four arguments and also how does javascript know which argument goes where in the subsequent code, since basically the argument names are all randomly assigned names by the user.

This is a seemingly simple project but I’ve been stuck on it for too long and doing it in vanilla JS wouldn’t make it any simpler. The logic of this project more or less makes sense, it’s just the React syntax and the logic behind this react syntax that has me stumped, and for which I’d greatly appreciate any point-by-point explanations.

Looks like a method to manage the variation of the duration of a time period^^

if (this.state.timerState == 'running') return;

  • Regardless of the argument you passed in, if the counter is running this method will do nothing^^
if (this.state.timerType == timerType) {
    ... 
    } else {
    ...
   }
  • First conditional statement: it discriminate if the timer you are changing (‘Session’ or ‘Break’) is the same saved in the actual state (the one visualized in the big center timer? Just arguing^^ )

CASE EQUAL:

      if (sign == "-" && currentLength != 1 ) {
        this.setState({[stateToChange]: currentLength - 1});
      } else if (sign == "+" && currentLength != 60) {
        this.setState({[stateToChange]: currentLength + 1});
      } 
  • It change the state [stateToChange] variable. Square brackets allows you to dinamically select a property of an object ( depending on the argument it receive it will select the relative property, in this case brkLength or seshLength in the state object)
    If it receive ‘-’ it reduces the value until 1 while if it receive ‘+’ it increase the value until 60

CASE NOT EQUAL:

    if (sign == "-" && currentLength != 1 ) {
        this.setState({[stateToChange]: currentLength - 1,
        timer: currentLength * 60 - 60});
      } else if (sign == "+" && currentLength != 60) {
        this.setState({[stateToChange]: currentLength + 1,
        timer: currentLength * 60 + 60});
      } 
  • Same as above, but this time it changes the timer value too.
    This happens only if not this.state.timerType == timerType, and looking at the arguments passed it makes sense:
setSeshLength(e) {
    this.lengthControl('seshLength', e.currentTarget.value, 
    this.state.seshLength, 'Break');
  }

If you’re changing the session length the timerType parameter is equal to ‘Break’ ( and the other way around i guess^^)

1 Like

A method (or a function if you prefer) can take as many arguments as you want, ideally you don’t want to pass more than 3 or 4 parameters because things can get messy quickly and also makes your code hard to maintain.

Not sure what you mean with this, but what you have in your sample code is not different than this very basic principle:

// You create a function, pass in some arguments
// And decide what to do with the given arguments
function add(a, b) {
 return a + b;
}

// When you call your function (or method), you define the arguments
// that you originally passed in when creating the function
// and the function is executed 
add(1 + 2) // expected output: 3

That sample code looks very fragile, I don’t think it’s good practice to have so many if else statements in the same method. It’s not only hard to read, but also hard to maintain. You change something and probably the entire method breaks. I would probably create a method for each functionality.

Is there something in specific that you don’t understand from your sample code?, there’s no much of React syntax other than state and setState and I’m guessing you have a solid understanding of how that works.