-
Notifications
You must be signed in to change notification settings - Fork 3.4k
7535 refactor picker compatible form #7807
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
7535 refactor picker compatible form #7807
Conversation
This reverts commit 5353111.
|
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
….com/LucioChavezFuentes/App into 7535_refactor-picker-compatible-form
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by @stitesExpensify in version: 1.1.54-0 🚀
|
|
@luacmartins @rushatgabhane @parasharrajat @stitesExpensify Can someone help out with the QA steps on this PR? Are we able to check it or this will be Internal? |
|
@mvtglobally please follow the steps listed under Tests:
|
@chiragsalian I fixed it, you need to provide key to Picker on ProfilePage.js In this case I set the state on key but it could be anything that reference the auto time zone of the user. The problem exists because I made a derivated state from props on More info here: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key |
|
@LucioChavezFuentes Looks like you have found a fix. This PR is under regression period, so could you please create a PR that fixes the deploy blocker? Thanks! |
|
I don't think #7807 (comment) is a good idea. the key will cause remounting. It will make a trivial component expensive. |
@LucioChavezFuentes @parasharrajat can't we just set the key to something like "timezonePicker" and call it a day? Or the key needs to change to force remounting (bad solution)? It's a deploy blocker so let's get it fixed asap! :) |
|
I don't think setting the key to something like "timezonePicker" would work. |
|
Meanwhile, any chance you guys can continue and discuss a more ideal solution and implement it when possible? 🙇♂️ |
|
Thanks for investigating and fixing this @chiragsalian! It seems that the fix was merged and deployed. @LucioChavezFuentes would you mind investigating other solutions that solve this problem without causing a remount? |
Sure. I'm on it. |
|
I don't have the context why we changed the implementation of Picker here. But instead of using #7807 (comment), you should directly pass the |
|
🚀 Deployed to production by @Julesssss in version: 1.1.54-1 🚀
|
|
Just passing I added logic to I made a profile of Profile on one render: ProfilePage performance on 3 renders:
Picker Timezone performance on 3 renders:
But, after all said, I must say @parasharrajat is right, Picker shouldn't have that complexity. I have an idea that might be a better solution but I need time to make tests. I'll post when I have something. |
|
Thanks for the detailed explanation @LucioChavezFuentes! Looking forward to your revised proposal! |
|
@LucioChavezFuentes I just noticed that this is also affecting Steps to reproduce:
The same is true for other usages of StatePicker in conjunction with AddressSearch. |
|
Looks like the temporary fix i added (as per this suggestion) ended up creating another deploy blocker issue. Investigating but any suggestions or a more permanent solution are welcome too 🙂 |
|
@chiragsalian @luacmartins I found a better solution: class BasePicker extends React.Component {
constructor(props) {
super(props);
this.state = {
-- selectedValue: this.props.value || this.props.defaultValue,
++ selectedValue: this.props.defaultValue,
};
this.updateSelectedValueAndExecuteOnChange = this.updateSelectedValueAndExecuteOnChange.bind(this);
}
updateSelectedValueAndExecuteOnChange(value) {
this.props.onInputChange(value);
this.setState({selectedValue: value});
}
render() {
const hasError = !_.isEmpty(this.props.errorText);
return (
<RNPickerSelect
onValueChange={this.updateSelectedValueAndExecuteOnChange}
items={this.props.items}
style={this.props.size === 'normal' ? basePickerStyles(this.props.disabled, hasError, this.props.focused) : styles.pickerSmall}
useNativeAndroidPickerStyle={false}
placeholder={this.props.placeholder}
-- value={this.state.selectedValue}
++ value={this.props.value || this.state.selectedValue}
Icon={() => this.props.icon(this.props.size)}
disabled={this.props.disabled}
fixAndroidTouchableBug
onOpen={this.props.onOpen}
onClose={this.props.onClose}
pickerProps={{
onFocus: this.props.onOpen,
onBlur: this.props.onBlur,
ref: this.props.innerRef,
}}
/>
);
}
}and key won't be neccesary to update on click checkbox on ProfilePage |
|
Thanks for the new solution @LucioChavezFuentes! I ran some quick tests and it seems to work well. Would you mind putting a PR up? We will go through the regular process to get this well tested and make sure we don't have any more blockers |
|
Sure, Im on it. |
|
PR of my last proposal is up! |





Details
Finish.
Finish. Console will return error if
isFormInputis settled totruebutinputIDis not settled at all.Finish. But...
I find an issue, (or expected behaviour?) I think is related to
Formcomponent.I run Storybook and I go to
Formtab and selectDefault. When I write new values on Inputs insideFormand I then click on submit button, only updated values inside Inputs withshouldSaveDraftprop settled totrueare submitted. The other Inputs only submit the dafult value. not the values showed in the UI.Should I attend this issue too? Is being attended by someone else? Or is this the expected behaviour?
It happens on
TextInputand I see it too onPicker.Finish.
Finish.
Finish. I created a
handleChangefunction and put it ononTextChange. It managesprops.onChangeandstate.selectValuevalue ofRNPickerSelectso it can change the value on UI.Finish. Though I leave a
hasErrorvariable based onerrorTextonBasePicker. I think is easier to readhasErrorthan!_.isEmpty(this.props.errorText)onstylelogic.Finish.
Finish. Created
hasErrorvariable explained on point 7. Apparently it is only used instylelogic.Finish.
Well, this was a tricky one.
refseems not to be exposed on all platforms.Web & Mobile Web:
Picker from https://github.com/react-native-picker/picker is being used inside
RNPickerSelect. Picker ref prop does not work on Web therefore it can not get<select>'srefthat Picker renders, so a pull request has been made with a potential fix to this issue. In any case, I implemented an alternative in/BasePicker/index.jsto scroll toPickeron clickfix the errors. IfPickerreturns aref, the implementation ofcomponentDidMountinside/BasePicker/index.jsand the move of base logic to/BasePicker/index.native.jswould not be neccesary.Desktop (mac):
Teorically works similar to Web, though I haven't tested the scroll on
fix the errorson this platform.Android:
Picker does return a
focus()method but I test it with@react-native-picker/pickeron version2.2.1. This library needs to be updated at least to1.16.0according to documentation in order tofocus()method be exposed.iOS: Same situation as Android.
@react-native-picker/pickermust be updated to exposerefwithfocus()method.Finish. I guess Storybook is the only way to see how
Pickerperforms insideFormcomponent. I haven't testedFormfunctionalities onPickerlike scroll on clickfix the errorson any other platform besides Storybook.Finish. My lint doesn't recognize any unused variable.
Extra.
Created a
Picker.stories.jsfor Storybook to testPickeralone.Posible Issues Found
FormwithshouldSaveDraftset to true are submitted.Fixed Issues
$ #7535
Tests
Make sure refactor changes does not break the current functionality of
Pickeron all platforms:Web, Mobile Web, Desktop, Android and iOS:
Prefered pronounsPickerto focus. A list of options should appear.savebutton.Profile Pageand enter again.Pickerinput.Prefered pronounsPicker.Profile Pagewithout save.Profile Page. The most recent Saved change value should populatePickernot the most recent change.Storybook Web and Web Mobile (Google Chrome for Android)
Test
Pickerbehaviour insideFormin Storybooknpm run storybook.Form-->DefaultPickervalues. The UI should change accordinglysubmitbuttonForm.stories.js(Expected Behaviour?)Test scroll to
Pickeron clickfix the errrorsin Storybook.Form.stories.js,InputError.argsand set non empty values as default to other input types besidesPickersnpm run storybookForm.stories.jsor shrink window enough to get the firstPickerout of view while we can seesubmitbutton.submitbutton.Pickererror(s) andfix the errorssentence should appear.fix the errors. The view should scroll and center to the first Picker on error.QA Steps
Android and iOS:
The
focus()method should be checked if it does the expected behaviour onFormcomponent.I only check if
focus()exist with aconsole.log(this.pickerRef.focus)insidecomponentDidUpdateinProfilePage.jsbut couldn't test its behaviour beacuse absecence ofFormcomponent in App.Tested On
StoryBook Form tab and App inside
ProfilePage.jsOnly on App inside
ProfilePage.jsScreenshots
Web
Mobile Web
Desktop
iOS
Android