-
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
Remove usage of setNativeProps #10934
Changes from all commits
8666d97
ecabcfc
1295ebb
27020f5
72bbc0b
ddfabdf
12fa935
e45288e
e2b07d2
1cce3d5
4c90e34
1bfc4e2
a0ff498
8528c0d
deeaef9
b77ab39
3298fa7
28fdeac
38fd5ad
e23f51c
103e340
1192191
237d0dd
7dd836f
0644e1d
e0fb68b
a8b8e7b
97ebb65
5f1ecfe
b4d3bdd
74cb3cb
cbf0415
358a77f
aaab06b
2122178
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,17 +36,13 @@ class InvertedFlatList extends React.Component { | |
this.props.innerRef(this.list); | ||
} | ||
|
||
if (this.list) { | ||
this.list | ||
.getScrollableNode() | ||
.addEventListener('wheel', this.invertedWheelEvent); | ||
|
||
this.list.setNativeProps({ | ||
style: { | ||
transform: 'translate3d(0,0,0) scaleY(-1)', | ||
}, | ||
}); | ||
if (!this.list) { | ||
return; | ||
} | ||
|
||
this.list | ||
.getScrollableNode() | ||
.addEventListener('wheel', this.invertedWheelEvent); | ||
} | ||
|
||
componentWillUnmount() { | ||
|
@@ -67,6 +63,7 @@ class InvertedFlatList extends React.Component { | |
ref={el => this.list = el} | ||
shouldMeasureItems | ||
contentContainerStyle={StyleSheet.compose(this.props.contentContainerStyle, styles.justifyContentEnd)} | ||
style={styles.translate0InvertY} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Context - we have to remove usage of @marcaaron do you remember if there's any downside to pass this style as a prop vs using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good Change if this works. the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
out of curiousity, do you remember what kind of issues? |
||
/> | ||
); | ||
} | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -10,26 +10,7 @@ class BasePicker extends React.Component { | |||
constructor(props) { | ||||
super(props); | ||||
|
||||
this.pickerValue = this.props.defaultValue; | ||||
|
||||
this.updateSelectedValueAndExecuteOnChange = this.updateSelectedValueAndExecuteOnChange.bind(this); | ||||
this.executeOnCloseAndOnBlur = this.executeOnCloseAndOnBlur.bind(this); | ||||
this.setNativeProps = this.setNativeProps.bind(this); | ||||
} | ||||
|
||||
/** | ||||
* This method mimicks RN's setNativeProps method. It's exposed to Picker's ref and can be used by other components | ||||
* to directly manipulate Picker's value when Picker is used as an uncontrolled input. | ||||
* | ||||
* @param {*} value | ||||
*/ | ||||
setNativeProps({value}) { | ||||
this.pickerValue = value; | ||||
} | ||||
|
||||
updateSelectedValueAndExecuteOnChange(value) { | ||||
this.props.onInputChange(value); | ||||
this.pickerValue = value; | ||||
} | ||||
|
||||
executeOnCloseAndOnBlur() { | ||||
|
@@ -42,12 +23,12 @@ class BasePicker extends React.Component { | |||
const hasError = !_.isEmpty(this.props.errorText); | ||||
return ( | ||||
<RNPickerSelect | ||||
onValueChange={this.updateSelectedValueAndExecuteOnChange} | ||||
onValueChange={this.props.onInputChange} | ||||
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.props.value || this.pickerValue} | ||||
value={this.props.value || this.props.defaultValue} | ||||
Comment on lines
-50
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The concept of defaultValue is unnecessary when we are using state-bound value prop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree! I'll explain why I didn't remove it in this PR. I think all Form components are state based / value prop driven. But Form.js passes I reckon we should do the cleanup in a follow-up PR. Line 154 in 97ebb65
I wanted to avoid adding more tests or break anything basically There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For example, We'd be introducing unrelated diffs and tests. |
||||
Icon={() => this.props.icon(this.props.size)} | ||||
disabled={this.props.disabled} | ||||
fixAndroidTouchableBug | ||||
|
@@ -57,15 +38,11 @@ class BasePicker extends React.Component { | |||
onFocus: this.props.onOpen, | ||||
onBlur: this.executeOnCloseAndOnBlur, | ||||
}} | ||||
ref={(node) => { | ||||
if (!node || !_.isFunction(this.props.innerRef)) { | ||||
ref={el => { | ||||
if (!_.isFunction(this.props.innerRef)) { | ||||
return; | ||||
} | ||||
|
||||
this.props.innerRef(node); | ||||
|
||||
// eslint-disable-next-line no-param-reassign | ||||
node.setNativeProps = this.setNativeProps; | ||||
this.props.innerRef(el); | ||||
}} | ||||
/> | ||||
); | ||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -29,6 +29,9 @@ const propTypes = { | |||||||||||||||
|
||||||||||||||||
/** Saves a draft of the input value when used in a form */ | ||||||||||||||||
shouldSaveDraft: PropTypes.bool, | ||||||||||||||||
|
||||||||||||||||
/** A callback method that is called when the value changes and it received the selected value as an argument */ | ||||||||||||||||
onInputChange: PropTypes.func.isRequired, | ||||||||||||||||
}; | ||||||||||||||||
|
||||||||||||||||
const defaultProps = { | ||||||||||||||||
|
@@ -47,6 +50,23 @@ class Picker extends PureComponent { | |||||||||||||||
this.state = { | ||||||||||||||||
isOpen: false, | ||||||||||||||||
}; | ||||||||||||||||
|
||||||||||||||||
this.onInputChange = this.onInputChange.bind(this); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
* Forms use inputID to set values. But Picker passes an index as the second parameter to onInputChange | ||||||||||||||||
* We are overriding this behavior to make Picker work with Form | ||||||||||||||||
* @param {String} value | ||||||||||||||||
* @param {Number} index | ||||||||||||||||
*/ | ||||||||||||||||
onInputChange(value, index) { | ||||||||||||||||
if (this.props.inputID) { | ||||||||||||||||
this.props.onInputChange(value, this.props.inputID); | ||||||||||||||||
return; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
this.props.onInputChange(value, index); | ||||||||||||||||
Comment on lines
+53
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is this change related to this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great question! @parasharrajat Anytime a Form input's value is changed, If you'll look at Form.js Lines 161 to 166 in 97ebb65
It keeps track of input values based on the key provided to it. So our expected function call looks something like this - Prerequisite: Picker is used in a Form. Now It passes the picker item's index as the second parameter. (source) So this is what actually gets called - Our Form based picker now will try to change the value of an input whose formID is 156. I'm just fixing this by passing the formID as the second param, because we don't care aobut the index lol There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This wasn't a problem before because previously, Form set the value using We're getting rid of that, so I had to fix Picker in this PR only. Line 166 in 1c78eb8
|
||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
render() { | ||||||||||||||||
|
@@ -72,6 +92,7 @@ class Picker extends PureComponent { | |||||||||||||||
value={this.props.value} | ||||||||||||||||
// eslint-disable-next-line react/jsx-props-no-spreading | ||||||||||||||||
{...pickerProps} | ||||||||||||||||
onInputChange={this.onInputChange} | ||||||||||||||||
/> | ||||||||||||||||
</View> | ||||||||||||||||
<InlineErrorText styles={[styles.mh3]}> | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,6 +144,7 @@ class ReportActionCompose extends React.Component { | |
end: props.comment.length, | ||
}, | ||
maxLines: props.isSmallScreenWidth ? CONST.COMPOSER.MAX_LINES_SMALL_SCREEN : CONST.COMPOSER.MAX_LINES, | ||
value: props.comment, | ||
}; | ||
} | ||
|
||
|
@@ -311,9 +312,6 @@ class ReportActionCompose extends React.Component { | |
addEmojiToTextBox(emoji) { | ||
const newComment = this.comment.slice(0, this.state.selection.start) | ||
+ emoji + this.comment.slice(this.state.selection.end, this.comment.length); | ||
this.textInput.setNativeProps({ | ||
text: newComment, | ||
}); | ||
this.setState(prevState => ({ | ||
selection: { | ||
start: prevState.selection.start + emoji.length, | ||
|
@@ -372,9 +370,9 @@ class ReportActionCompose extends React.Component { | |
* @param {String} newComment | ||
*/ | ||
updateComment(newComment) { | ||
this.textInput.setNativeProps({text: newComment}); | ||
this.setState({ | ||
isCommentEmpty: !!newComment.match(/^(\s|`)*$/), | ||
value: newComment, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add |
||
}); | ||
|
||
// Indicate that draft has been created. | ||
|
@@ -627,7 +625,6 @@ class ReportActionCompose extends React.Component { | |
this.setState({isDraggingOver: false}); | ||
}} | ||
style={[styles.textInputCompose, this.props.isComposerFullSize ? styles.textInputFullCompose : styles.flex4]} | ||
defaultValue={this.props.comment} | ||
maxLines={this.state.maxLines} | ||
onFocus={() => this.setIsFocused(true)} | ||
onBlur={() => this.setIsFocused(false)} | ||
|
@@ -640,6 +637,7 @@ class ReportActionCompose extends React.Component { | |
isFullComposerAvailable={this.state.isFullComposerAvailable} | ||
setIsFullComposerAvailable={this.setIsFullComposerAvailable} | ||
isComposerFullSize={this.props.isComposerFullSize} | ||
value={this.state.value} | ||
/> | ||
</View> | ||
</> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,7 +97,6 @@ class ReportActionItemMessageEdit extends React.Component { | |
* @param {String} newDraft | ||
*/ | ||
updateDraft(newDraft) { | ||
this.textInput.setNativeProps({text: newDraft}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's make sure this issue doesn't come back There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, I have already added tests for it |
||
this.setState({draft: newDraft}); | ||
|
||
// This component is rendered only when draft is set to a non-empty string. In order to prevent component | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -260,7 +260,7 @@ class ProfilePage extends Component { | |
value: '', | ||
label: this.props.translate('profilePage.selectYourPronouns'), | ||
}} | ||
defaultValue={pronounsPickerValue} | ||
value={pronounsPickerValue} | ||
/> | ||
{this.state.hasSelfSelectedPronouns && ( | ||
<View style={styles.mt2}> | ||
|
@@ -290,7 +290,6 @@ class ProfilePage extends Component { | |
label={this.props.translate('profilePage.timezone')} | ||
items={timezones} | ||
isDisabled={this.state.isAutomaticTimezone} | ||
defaultValue={this.state.selectedTimezone} | ||
value={this.state.selectedTimezone} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove other usages of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't because it's controlled. |
||
/> | ||
</View> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this means that inputs are no longer uncontrolled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luacmartins yes, that's right