본문 바로가기
Mobile Application/React Native

[React Native] Debounce를 활용한 검색창 & 자동완성 구현하기 || Typescript | Flatlist ||

by 개발이 체질인 나그네 2023. 4. 20.
반응형

 

시연영상.gif

안녕하세요. 개발의 체질 최원혁입니다. 이번 게시글에서는 앱 개발을 할때 검색창과 자동완성 기능을 구현하는 방법에 대해 알아보겠습니다.

📌전체 코드는 게시글 하단에 Github주소를 남겨 두겠습니다!~!

 

 

# 1. 변수 설정

interface ISearchData {
    cityname:string;
    id:string;
}

const [loading, setLoading] = useState(true);
const [list, setList] = useState<ISearchData[]>([]);
const [keyword, setKeyword] = useState<string>('');
  • loading : 검색 시, UI상에 보여지는 로딩 아이콘 On/Off
  • list : 검색어가 포함된 데이터 리스트
  • keyword : 검색 키워드

 

# 2. 검색 창(TextInput) 구현

const onChangeKeyword = useCallback((text: string) => {
    setKeyword(text.trim());
  }, []);

return (
	...
    
      <TextInput
        clearButtonMode="always"
        onChangeText={onChangeKeyword}
        placeholderTextColor={'#929292'}
        style={styles.textInput}
        placeholder="닉네임 검색"
        value={keyword}
      />
  
  	...
  )
  1. onChangeKeyword() 함수를 통해 스페이스(공백)을 검색에서 제거 했습니다.(불필요시 생략하면 됩니다.)
  2. TextInputonChangeText에 onChangeKeyword() 함수를 넣어 검색어가 바뀔때 마다 실행 되도록 합니다.
  3. TextInputvalue에 만들어둔 변수 keyword를 넣어 값을 저장합니다.

 

# 3. Debounce 기법을 활용한 검색 기능 구현

Debounce 란?
Debounce은 함수를 여러 번 호출하고 마지막 호출에서 일정 시간이 지난 후 해당 함수의 기능이 동작하는 기법입니다.

Debounce를 사용하는 경우 검색창에서 자동 완성을 구현해야 하는 경우 또는 마우스를 빠르게 여러 번 클릭했을 때, 마지막 클릭에서 기능이 동작해야 하는 경우 사용할 수 있습니다. 

 

예를 들어, 검색 창에 "Korea"를 입력하게되면, 검색 기능 및 API를 5번 호출하게 됩니다. 하지만 Debounce 기법을 활용하면 키워드 입력 후 n초 후에 기능이 호출되며, n초 이내에 여러번 키워드를 입력하면 n초가 초기화 되기에, 키워드 입력이 끝난 후에 기능을 한번 호출하게 됩니다.

 

const searchAPI = (keyword:string) => {
	// searchData is dummy data
	return searchData.filter((v) => v.cityname.includes(keyword))
}
  
  useEffect(() => {
    const getList = () => {
      try {
        setLoading(true);
        // if have API, set here

        // I just use dummy data.
        const data = searchAPI(keyword);
        setList(data);
      } catch (error) {
        // code error
      } finally {
        setLoading(false);
      }
    };

    const debounce = setTimeout(() => {
      getList();
    }, 200);

    return () => {
      clearTimeout(debounce);
    };
  }, [keyword]);
  
  return (
      ...
      )
  1. useEffect를 활용하여 keyword가 변경 될때, 내부 코드가 호출되도록 합니다.
  2.  getList() 함수를 활용하여 검색할 데이터 배열에 입력된 keyword가 포함된 데이터를 list변수에 저장합니다.
  3. debounce() 함수에 setTimeout() 함수를 활용하여 debounce를 구현합니다. 저는 입력후 0.2초 뒤에 함수를 호출하도록 구현했습니다. 

 

# 4. 자동완성 기능 구현(Flatlist)

return (
		...
        {loading ? (
                <View
                  style={{
                  ...
                  }}>
                  <ActivityIndicator color={'#fff'} />
                </View>
              ) : (
                <FlatList
                  keyExtractor={item => item.id}
                  data={list}
                  disableScrollViewPanResponder={true}
                  ListEmptyComponent={() => (
                    <View style={...}>
                      <Text
                        style={...}>
                        검색 내용이 없습니다.
                      </Text>
                    </View>
                  )}
                  renderItem={items => {
                    const {item} = items;
                    return (
                      <TouchableOpacity
                        onPressIn={() => Keyboard.dismiss()}
                        onPress={() => Alert.alert('클릭 시: 동작 코드')}
                        activeOpacity={1}
                        style={styles.applicationBox}
                        key={items.index}>
                        <View
                          style={...}></View>
                        <View
                          style={...}>
                          <Text style={styles.fontStyle}>Id {item.id} : </Text>
                          <Text style={[styles.fontStyle, {fontWeight: 'bold'}]}>
                            {item.cityname}
                          </Text>
                        </View>
                      </TouchableOpacity>
                    );
                  }}
                />
              )}
              ...
 )
  1. loading 상태에서는 로딩 아이콘이 보여지게 구현합니다.
  2. flatlistdata에 검색어가 포함된 자동완성 리스트인 list를 저장합니다.
  3. disableScrollViewPanResponder={true} 로 설정하여 리스트를 클릭 할 수 있도록 합니다.
  4. onPressIn={() => Keyboard.dismiss()}는 리스트 클릭 시, 다음 동작에서 키보드가 활성화 되있으면 UI상으로 불편하여 넣었습니다.( 불 필요시 생략 가능)
  5. style는 코드 가독성을 위해 우선 제거했습니다. 전체 코드는 아래 Giuhub 링크를 남겨 두겠습니다.

 

 

 

# 5.  전체 코드 (Github)

 

GitHub - imelon2/ReactNative_Playground

Contribute to imelon2/ReactNative_Playground development by creating an account on GitHub.

github.com

 

 

 

반응형

댓글