Skip to content

Commit

Permalink
refactor: searchbar rewritten as functional component (#2132)
Browse files Browse the repository at this point in the history
## Description

This PR intents to change SearchBar component into a functional
component.

## Changes

Rewritten SearchBar component as function leveraging useImperativeHandle
to apply new methods

<!--

## Screenshots / GIFs

Here you can add screenshots / GIFs documenting your change.

You can add before / after section if you're changing some behavior.

### Before

### After

-->

## Test code and steps to reproduce

<!--
Please include code that can be used to test this change and short
description how this example should work.
This snippet should be as minimal as possible and ready to be pasted
into editor (don't exclude exports or remove "not important" parts of
reproduction example)
-->

## Checklist

- [ ] Included code example that can be used to test this change
- [ ] Updated TS types
- [ ] Updated documentation: <!-- For adding new props to native-stack
-->
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/native-stack/README.md
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/src/types.tsx
- [ ]
https://github.com/software-mansion/react-native-screens/blob/main/src/native-stack/types.tsx
- [ ] Ensured that CI passes
  • Loading branch information
alduzy authored May 15, 2024
1 parent fb0ce28 commit f3630d9
Showing 1 changed file with 55 additions and 64 deletions.
119 changes: 55 additions & 64 deletions src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactNode } from 'react';
import React from 'react';
import {
isSearchBarAvailableForCurrentPlatform,
SearchBarCommands,
Expand All @@ -12,80 +12,71 @@ import SearchBarNativeComponent, {
} from '../fabric/SearchBarNativeComponent';

export const NativeSearchBar: React.ComponentType<SearchBarProps> &
typeof NativeSearchBarCommands = SearchBarNativeComponent as any;
typeof NativeSearchBarCommands =
SearchBarNativeComponent as unknown as React.ComponentType<SearchBarProps> &
SearchBarCommandsType;
export const NativeSearchBarCommands: SearchBarCommandsType =
SearchBarNativeCommands as any;
SearchBarNativeCommands as SearchBarCommandsType;

type NativeSearchBarRef = React.ElementRef<typeof NativeSearchBar>;

type SearchBarCommandsType = {
blur: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
focus: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
clearText: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
toggleCancelButton: (
viewRef: React.ElementRef<typeof NativeSearchBar>,
flag: boolean
) => void;
setText: (
viewRef: React.ElementRef<typeof NativeSearchBar>,
text: string
) => void;
cancelSearch: (viewRef: React.ElementRef<typeof NativeSearchBar>) => void;
blur: (viewRef: NativeSearchBarRef) => void;
focus: (viewRef: NativeSearchBarRef) => void;
clearText: (viewRef: NativeSearchBarRef) => void;
toggleCancelButton: (viewRef: NativeSearchBarRef, flag: boolean) => void;
setText: (viewRef: NativeSearchBarRef, text: string) => void;
cancelSearch: (viewRef: NativeSearchBarRef) => void;
};

class SearchBar extends React.Component<SearchBarProps> {
nativeSearchBarRef: React.RefObject<SearchBarCommands>;

constructor(props: SearchBarProps) {
super(props);
this.nativeSearchBarRef = React.createRef();
}
function SearchBar(props: SearchBarProps, ref: React.Ref<SearchBarCommands>) {
const searchBarRef = React.useRef<SearchBarCommands | null>(null);

_callMethodWithRef(method: (ref: SearchBarCommands) => void) {
const ref = this.nativeSearchBarRef.current;
if (ref) {
method(ref);
} else {
console.warn(
'Reference to native search bar component has not been updated yet'
React.useImperativeHandle(ref, () => ({
blur: () => {
_callMethodWithRef(ref => NativeSearchBarCommands.blur(ref));
},
focus: () => {
_callMethodWithRef(ref => NativeSearchBarCommands.focus(ref));
},
toggleCancelButton: (flag: boolean) => {
_callMethodWithRef(ref =>
NativeSearchBarCommands.toggleCancelButton(ref, flag)
);
}
}
},
clearText: () => {
_callMethodWithRef(ref => NativeSearchBarCommands.clearText(ref));
},
setText: (text: string) => {
_callMethodWithRef(ref => NativeSearchBarCommands.setText(ref, text));
},
cancelSearch: () => {
_callMethodWithRef(ref => NativeSearchBarCommands.cancelSearch(ref));
},
}));

blur() {
this._callMethodWithRef(ref => NativeSearchBarCommands.blur(ref));
}

focus() {
this._callMethodWithRef(ref => NativeSearchBarCommands.focus(ref));
}
const _callMethodWithRef = React.useCallback(
(method: (ref: SearchBarCommands) => void) => {
const ref = searchBarRef.current;
if (ref) {
method(ref);
} else {
console.warn(
'Reference to native search bar component has not been updated yet'
);
}
},
[searchBarRef]
);

toggleCancelButton(flag: boolean) {
this._callMethodWithRef(ref =>
NativeSearchBarCommands.toggleCancelButton(ref, flag)
if (!isSearchBarAvailableForCurrentPlatform) {
console.warn(
'Importing SearchBar is only valid on iOS and Android devices.'
);
return View as unknown as React.ReactNode;
}

clearText() {
this._callMethodWithRef(ref => NativeSearchBarCommands.clearText(ref));
}

setText(text: string) {
this._callMethodWithRef(ref => NativeSearchBarCommands.setText(ref, text));
}

cancelSearch() {
this._callMethodWithRef(ref => NativeSearchBarCommands.cancelSearch(ref));
}

render() {
if (!isSearchBarAvailableForCurrentPlatform) {
console.warn(
'Importing SearchBar is only valid on iOS and Android devices.'
);
return View as any as ReactNode;
}

return <NativeSearchBar {...this.props} ref={this.nativeSearchBarRef} />;
}
return <NativeSearchBar {...props} ref={searchBarRef} />;
}

export default SearchBar;
export default React.forwardRef<SearchBarCommands, SearchBarProps>(SearchBar);

0 comments on commit f3630d9

Please sign in to comment.