Home > Blockchain >  React setState depending on sibling's state
React setState depending on sibling's state

Time:10-03

Desired behaviour: birth date validation >> if selected birth year 2003 then re-render seleted birth month to october.

Basically what I have now is three components in a form, looking like this:

 <FormProvider >
  <form action="#" method="POST" > 
    < SelectBirthYear
      years={years}
      value={selectedYear}
      onChange={setSelectedYear}/>
     </div>
          
     < SelectBirthMonth 
       startYear={startYear}
       selectedYear={selectedYear}
       months={months}
       value={selectedMonth}
       reducedMonths={reducedMonths}
       onChange={watchYearChange}/>
      </div>
          
     <SelectBirthDay
      days={days}
      value={selectedDay}
      onChange={setSelectedDay}
     />
 </form>
</FormProvider>

)

This is not the entire code - please see sandbox below. What I have achieved so far, is that if the selected year is 2003, the selection of months will only go till october (month now). But if I choose year 2002, all 12 months will appear in the select. So the user chooses the birth date 2002.12 and then re-selects the birth year to 2003, he can trick the select and set the birth date to 2003.12, which means the age is under 18 (as of today). So, as soon as the year gets re-selected to 2003, I'd like the selected month to get updated. For this I tried to write a function watchYearChange which I wrapped into useEffect, which watches selected year. Here is a bit:

const [selectedMonth, setSelectedMonth] = useState(months[0]);
  
const watchYearChange = () => Number(selectedYear.name) == startYear ? setSelectedMonth(months[9]) : setSelectedMonth(selectedMonth);
    
useEffect(() => watchYearChange, [selectedYear]); 

Unfortunatelly I can't select any month at all anymore, as it just get's set to months[9]. As I am new to react, I am out of ideas, how to watch the selectedYear and just re-render selected month once, if the selectedYear is 2003.

Here is my sandbox

CodePudding user response:

You should be able to change the month based on the Listbox options selection in your SelectBirthMonth component. Therefore, you need to pass a separate onChange function (monthSelect function below) from Form component to SelectBirthMonth component.

First, create monthSelect function as follows.

  const monthSelect = (data) => {
    setSelectedMonth(months[data.id - 1]);
  };

Then, pass it to the child component.

                <SelectBirthMonth
                  startYear={startYear}
                  selectedYear={selectedYear}
                  months={months}
                  value={selectedMonth}
                  reducedMonths={reducedMonths}
                  onChange={monthSelect}
                />

For more info, check this for code-sandbox.

For watchYearChange, instead of ternary, you can use if condition as follows to avoid same state setting when condition is false.

  const watchYearChange = () =>
    if(Number(selectedYear.name) == startYear){
       setSelectedMonth(months[9])
    }
  • Related