반응형
✔️ 필요성
RN에서 AutoComplete 검색창을 만들어야 해서 기존에 만들어진 AutoComplete 자동완성 검색창 라이브러리인 react-native-autocomplete-dropdown 라이브러리를 사용하기로 했다.
github에서 제공하는 걸 보니 나쁘지 않은 것 같아서 사용하기로 마음먹음
https://github.com/onmotion/react-native-autocomplete-dropdown
✔️ 활용코드
이건 순전히 내 기록용으로 남기기 위해서 활용코드를 만듦. AutocompleteSearch라는 공통 컴포넌트를 만들고, 각각의 검색창마다 이걸 공통으로 가져다 쓸거다.
suggestion 아이템들이 나오는 부분을 좀 더 예쁘게 꾸미고 싶기 때문에 renderItem을 받아서 사용
import React, {useRef, useState} from 'react';
import {
AutocompleteDropdown,
TAutocompleteDropdownItem,
} from 'react-native-autocomplete-dropdown';
interface Props {
placeholder?: string;
dataset: TAutocompleteDropdownItem[];
renderItem?: (
item: TAutocompleteDropdownItem,
searchText: string,
) => JSX.Element;
}
const AutoCompleteSearch = ({placeholder, dataset, renderItem}: Props) => {
const [selectedItem, setSelectedItem] = useState(null);
const dropdownController = useRef(null);
return (
<AutocompleteDropdown
clearOnFocus={false}
closeOnBlur={true}
closeOnSubmit={false}
// initialValue={{id: '2'}} // or just '2'
suggestionsListMaxHeight={200}
onSelectItem={() => setSelectedItem}
controller={controller => {
dropdownController.current = controller;
}}
textInputProps={{
placeholder: placeholder,
}}
containerStyle={{flexGrow: 1, flexShrink: 1, width: 250}}
dataSet={dataset}
emptyResultText={'결과가 없습니다.'}
renderItem={renderItem}
/>
);
};
export default AutoCompleteSearch;
AutocompleteSearch 위에서 만들어놓은 컴포넌트를 받아서 initialData를 집어넣고 또 옆에있는 아이콘을 누르면 데이터(list)가 바뀌게끔 짜놓은 코드. initialData랑 data가 두 개 있는 건... 그냥 눈감아주길
import React, {useEffect, useState} from 'react';
import styled from 'styled-components/native';
import RegisterCard from '~/components/RegisterCard';
import AutoCompleteSearch from '~/components/AutoCompleteSearch';
import SubwayLineTag from '~/components/SubwayLineTag';
import IconComma from '~/components/IconComma';
import {TAutocompleteDropdownItem} from 'react-native-autocomplete-dropdown';
const Text = styled.Text``;
const RenderItemContainer = styled.View`
flex-direction: row;
`;
const StyledSubwayLineTag = styled(SubwayLineTag)`
justify-content: center;
margin-left: 5px;
`;
const StyledIconComma = styled(IconComma)`
justify-content: center;
`;
const initialData = [
{
id: '1',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: true,
},
{
id: '2',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: false,
},
{
id: '3',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: true,
},
{
id: '4',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: false,
},
{
id: '5',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: false,
},
{
id: '6',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: false,
},
{
id: '7',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: false,
},
{
id: '8',
title: '강남',
subwayLine: '2',
nextStation: '역삼',
favoriteSelected: false,
},
];
interface Props {
onPress(): void;
isSelected: boolean;
}
const IconCommaButton = ({onPress, isSelected}: Props) => {
return (
<StyledIconComma size={'s'} onPress={onPress} strokeOnly={!isSelected} />
);
};
const Register = () => {
const [list, setList] = useState<any[]>(initialData);
useEffect(() => {}, [list]);
const onPress = (id: string) => {
const nextList = list.map(item =>
item.id === id
? {...item, favoriteSelected: !item.favoriteSelected}
: item,
);
setList(nextList);
};
const renderItem = (item: TAutocompleteDropdownItem, text: string) => (
<RenderItemContainer>
<StyledSubwayLineTag subwayLine={list[Number(item.id) - 1].subwayLine} />
<Text style={{color: 'black', padding: 15}}>
{item.title} | {list[Number(item.id) - 1].nextStation}방면
</Text>
<IconCommaButton
onPress={() => onPress(item.id)}
isSelected={list[Number(item.id) - 1].favoriteSelected}
/>
</RenderItemContainer>
);
const dataset = [
{id: '1', title: '강남역'},
{id: '2', title: '강일역'},
{id: '3', title: '강동역'},
{id: '4', title: '을지로입구역'},
{id: '5', title: '을지로3가역'},
{id: '6', title: '을지로4가역'},
{id: '7', title: '동대문역사문화공원역'},
{id: '8', title: '수원역'},
];
return (
<AutoCompleteSearch
dataset={dataset}
renderItem={renderItem}
placeholder={'검색해주세요'}
/>
);
};
export default Register;
반응형
'프론트엔드 앱 > React-native' 카테고리의 다른 글
[에러해결] Expected style width to contain units (0) | 2021.12.16 |
---|---|
[자동완성검색] UI Kitten Autocomplete 사용하기 / 기본편 (0) | 2021.12.15 |
React Native에서 대각선(Diagonal Line) 그리기 (0) | 2021.12.13 |
[에러] React Native version mismatch 해결 (0) | 2021.12.10 |
styled-components 에러해결 : ViewProps & RefAttributes<View> & ThemeProps<DefaultTheme> 형식에 속성이 없습니다 (0) | 2021.12.07 |