프론트엔드 앱/React-native

[자동완성검색] react-native-autocomplete-dropdown 사용하기

세리둥절 2021. 12. 15. 16:59
반응형

✔️ 필요성

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;
반응형