Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calendar: "mask" prop for the component makes every state appear as "undefined" inside the onChange function #4418

Closed
okzampo opened this issue May 18, 2023 · 5 comments
Labels
Resolution: By Design The behavior in the issue is by design and the component exhibits the expected behavior

Comments

@okzampo
Copy link

okzampo commented May 18, 2023

Describe the bug

While using the "mask" prop, if you input a date, every useState value appears as undefined. This is not the case if clicking on the calendar. I don't think there is anymore to add.

Reproducer

No response

PrimeReact version

8.1.1

React version

18.x

Language

ES6

Build / Runtime

Create React App (CRA)

Browser(s)

No response

Steps to reproduce the behavior

const [state, setState] = useState("hello");

const greetMe = () => {
console.log(state);
}

...
<Calendar ... mask={"99/99/9999 99:99"} onChange={greetMe}/>

Expected behavior

When inputing the date by keyboard, the onChange function should log "undefined".

When clicking on a date, the onChange function should log "hello"

@okzampo okzampo added the Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible label May 18, 2023
@melloware melloware changed the title The "mask" prop for the Calendar component makes every state appear as "undefined" inside the onChange function Calendar: "mask" prop for the component makes every state appear as "undefined" inside the onChange function May 18, 2023
@melloware
Copy link
Member

Can you see if your issue is similar to: #4030

Also you are using 8.1.1 have you tried 8.7.3 or 9.4.0?

@melloware
Copy link
Member

Nevermind you are not using state correctly here is a proper reproducer showing it works.

https://stackblitz.com/edit/react-xcbh3m?file=src%2FApp.js

The onChange is fired with or without mask on every keystroke. But using useEffect the console will only display when the date actually changes.

@melloware melloware closed this as not planned Won't fix, can't repro, duplicate, stale May 18, 2023
@melloware melloware added Resolution: By Design The behavior in the issue is by design and the component exhibits the expected behavior and removed Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible labels May 18, 2023
@okzampo
Copy link
Author

okzampo commented May 19, 2023

I am sorry, I think you deeply misunderstood me. Your solution is pretty basic React, I am talking about something different: I don't care about the value, I care about accessibility to other states.

In my specific case, each component has its value as a state. Because of accessibiliy reasons, I have to define a different state (a map of values) which I need in order to do some operations (calculate durations etc.)

const [myMap, setMyMap] = useState({})

it gets successfully valorized by an useEffect the first time the component gets opened.

useEffect(()=>{
   if(outerValue && Object.keys(outerValue).length > 0) {
      setMyMap(value); //containing keys and values
   } else {
      setMyMap({field1: null, field2: null ...}); //initialized with only keys
   }
}, [outerValue]);    

outerValue is used in order to initialize the myMap state. It comes from the props of my custom component (which encapsulates every field component, but not the form).

For different component, I use the following function when calling the "onChange" prop:

const handleChange = (field, value) => {
   if(Object.keys(myMap).length > 0 ){
      let newMap = clone(myMap); //function that clones "myMap"
      newMap[field] = value;
      setMyMap(newMap);
   }
}

As previously stated, the values of my components in the form does not depend on myMap.
Wherever i use it, the handleChange function works fine. When it is about the Calendar component with the "mask" prop, it suddently stops working, BUT ONLY WHEN I INPUT THE DATE (when I pick it by clicking, it works as intended).

//...
<Calendar 
   value={ownValue} 
   mask={"99/99/9999 99:99"} 
   onChange=(e => {
      setOwnValue( e.value ); //I don't care if this is null or if this is a date.
      console.log(myMap);
      onChange("date",e.value);
   })
}

It happens that, for whatever state I use, when I input the date, the value from the state equals to the value when defining it (the one in the useState(...), to be clear). This clearly stops my handleChange function to work as intended (since the myMap state gets initialized as an empty map, so it does not enter the if clause). ownValue gets changed correctly.

I do not think this is a design choice.

@melloware
Copy link
Member

Your code sounds like a mess? I don't understand what you are trying to accomplish?

Can you please provide a code sandbox reproducer showing your issue like I have provided?

@melloware
Copy link
Member

Also why not this...

const handleChange = (field, value) => {
   if(Object.keys(myMap).length > 0 ){
      if (myMap[field] === value) { return;} // do not clone the map and update state if this field is not changing?
      let newMap = clone(myMap); //function that clones "myMap"
      newMap[field] = value;
      setMyMap(newMap);
   }
}

Basically check before cloning and updating state that the field is even changing?

 if (myMap[field] === value) { return;} // do not clone the map and update state if this field is not changing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: By Design The behavior in the issue is by design and the component exhibits the expected behavior
Projects
None yet
Development

No branches or pull requests

2 participants