-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
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
isFormInput
is settled totrue
butinputID
is not settled at all.Finish. But...
I find an issue, (or expected behaviour?) I think is related to
Form
component.I run Storybook and I go to
Form
tab and selectDefault
. When I write new values on Inputs insideForm
and I then click on submit button, only updated values inside Inputs withshouldSaveDraft
prop settled totrue
are 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
TextInput
and I see it too onPicker
.Finish.
Finish.
Finish. I created a
handleChange
function and put it ononTextChange
. It managesprops.onChange
andstate.selectValue
value ofRNPickerSelect
so it can change the value on UI.Finish. Though I leave a
hasError
variable based onerrorText
onBasePicker
. I think is easier to readhasError
than!_.isEmpty(this.props.errorText)
onstyle
logic.Finish.
Finish. Created
hasError
variable explained on point 7. Apparently it is only used instyle
logic.Finish.
Well, this was a tricky one.
ref
seems 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>
'sref
that 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.js
to scroll toPicker
on clickfix the errors
. IfPicker
returns aref
, the implementation ofcomponentDidMount
inside/BasePicker/index.js
and the move of base logic to/BasePicker/index.native.js
would not be neccesary.Desktop (mac):
Teorically works similar to Web, though I haven't tested the scroll on
fix the errors
on this platform.Android:
Picker does return a
focus()
method but I test it with@react-native-picker/picker
on version2.2.1
. This library needs to be updated at least to1.16.0
according to documentation in order tofocus()
method be exposed.iOS: Same situation as Android.
@react-native-picker/picker
must be updated to exposeref
withfocus()
method.Finish. I guess Storybook is the only way to see how
Picker
performs insideForm
component. I haven't testedForm
functionalities onPicker
like scroll on clickfix the errors
on any other platform besides Storybook.Finish. My lint doesn't recognize any unused variable.
Extra.
Created a
Picker.stories.js
for Storybook to testPicker
alone.Posible Issues Found
Form
withshouldSaveDraft
set to true are submitted.Fixed Issues
$ #7535
Tests
Make sure refactor changes does not break the current functionality of
Picker
on all platforms:Web, Mobile Web, Desktop, Android and iOS:
Prefered pronouns
Picker
to focus. A list of options should appear.save
button.Profile Page
and enter again.Picker
input.Prefered pronouns
Picker
.Profile Page
without save.Profile Page
. The most recent Saved change value should populatePicker
not the most recent change.Storybook Web and Web Mobile (Google Chrome for Android)
Test
Picker
behaviour insideForm
in Storybooknpm run storybook
.Form
-->Default
Picker
values. The UI should change accordinglysubmit
buttonForm.stories.js
(Expected Behaviour?)Test scroll to
Picker
on clickfix the errrors
in Storybook.Form.stories.js
,InputError.args
and set non empty values as default to other input types besidesPicker
snpm run storybook
Form.stories.js
or shrink window enough to get the firstPicker
out of view while we can seesubmit
button.submit
button.Picker
error(s) andfix the errors
sentence 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 onForm
component.I only check if
focus()
exist with aconsole.log(this.pickerRef.focus)
insidecomponentDidUpdate
inProfilePage.js
but couldn't test its behaviour beacuse absecence ofForm
component in App.Tested On
StoryBook Form tab and App inside
ProfilePage.js
Only on App inside
ProfilePage.js
Screenshots
Web
Mobile Web
Desktop
iOS
Android