fix attempting to focus disabled textinputs (#30695)
Summary: when we call `focus()` upon a TextInput ref which has prop `editable=false` it marks the textinput as focused in `TextInputState` even though the focus is rejected by textinput itself because it is not editable. then, when you change `editable` prop to `true` and call `focus` again, [this condition](e912c462eb/Libraries/Components/TextInput/TextInputState.js (L46)
) or rather [this one](1b2b2198e1/Libraries/Components/TextInput/TextInputState.js (L89)
) will evaluate to `false` and focus will not happen even though it can and should happen. see also https://github.com/facebook/react-native/blob/0.64-stable/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js#L3895 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [General] [Fixed] - `focus()` on TextInput to respect its `editable` state Pull Request resolved: https://github.com/facebook/react-native/pull/30695 Test Plan: Create a `TextInput` with prop `editable=false` and call `ref.current.focus()` upon its ref. TextInput should not be marked as focused in `TextInputState`. Reviewed By: yungsters Differential Revision: D34357913 Pulled By: lunaleaps fbshipit-source-id: 9a2fb819bbb05ef213c9b5d739dec583ae0a3e6f
This commit is contained in:
Родитель
83ab3615c5
Коммит
8a5460ce80
|
@ -73,7 +73,7 @@ function blurField(textFieldID: ?number) {
|
|||
/**
|
||||
* @param {number} TextInputID id of the text field to focus
|
||||
* Focuses the specified text field
|
||||
* noop if the text field was already focused
|
||||
* noop if the text field was already focused or if the field is not editable
|
||||
*/
|
||||
function focusTextInput(textField: ?ComponentRef) {
|
||||
if (typeof textField === 'number') {
|
||||
|
@ -86,7 +86,15 @@ function focusTextInput(textField: ?ComponentRef) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (currentlyFocusedInputRef !== textField && textField != null) {
|
||||
if (textField != null) {
|
||||
const fieldCanBeFocused =
|
||||
currentlyFocusedInputRef !== textField &&
|
||||
// $FlowFixMe - `currentProps` is missing in `NativeMethods`
|
||||
textField.currentProps?.editable !== false;
|
||||
|
||||
if (!fieldCanBeFocused) {
|
||||
return;
|
||||
}
|
||||
focusInput(textField);
|
||||
if (Platform.OS === 'ios') {
|
||||
// This isn't necessarily a single line text input
|
||||
|
|
|
@ -79,9 +79,26 @@ describe('TextInput tests', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should have support being focused and unfocused', () => {
|
||||
function createTextInput(extraProps) {
|
||||
const textInputRef = React.createRef(null);
|
||||
ReactTestRenderer.create(<TextInput ref={textInputRef} value="value1" />);
|
||||
ReactTestRenderer.create(
|
||||
<TextInput ref={textInputRef} value="value1" {...extraProps} />,
|
||||
);
|
||||
return textInputRef;
|
||||
}
|
||||
|
||||
it('focus() should not do anything if the TextInput is not editable', () => {
|
||||
const textInputRef = createTextInput({editable: false});
|
||||
// currentProps is the property actually containing props at runtime
|
||||
textInputRef.current.currentProps = textInputRef.current.props;
|
||||
expect(textInputRef.current.isFocused()).toBe(false);
|
||||
|
||||
TextInput.State.focusTextInput(textInputRef.current);
|
||||
expect(textInputRef.current.isFocused()).toBe(false);
|
||||
});
|
||||
|
||||
it('should have support for being focused and blurred', () => {
|
||||
const textInputRef = createTextInput();
|
||||
|
||||
expect(textInputRef.current.isFocused()).toBe(false);
|
||||
ReactNative.findNodeHandle = jest.fn().mockImplementation(ref => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче