본문 바로가기
앱 개발

[react-native] 특정 문자를 포함한 데이터를 찾아 카테고리별 다른 화면 보여주기

by evekang 2022. 6. 15.

 

 

 

 

스파르타코딩클럽에서 나온 예제를 토대로 나만의 앱을 만드는 중인데,

여기서는 state에다 filter()를 사용해서 해당 카테고리에 해당하는 리스트만 보여주는 형식이었다.

 

 

data.json에 {category:"전체보기", category:"생활".....} 이런 식으로 항목이 딱딱 정해져 있음.

그리고 구현 코드.

const [state, setState] = useState([]) 						
const [cateState, setCateState] = useState([])				

useEffect(() => {  											
    setTimeout(() => { 									
          setState(tip); 									
          setCateState(tip);
          setReady(false);
        });
    }, 1000);
  }, []);
  
  
  const category = (cate) => { 							
    if (cate == "전체보기") {							
      setCateState(state);									
    } else { 
      setCateState( 
        state.filter((d) => {							
          return d.category == cate;
        })
      );
    }
  };
  
  return ready ? (
    <Loading />
  ) : (
    <ScrollView style={styles.container}>
      <Image style={styles.mainImage} source={{ uri: main }} />
      <ScrollView
        style={styles.middleContainer}
        horizontal
        indicatorStyle={"white"}
      >
        <TouchableOpacity
          style={styles.middleButtonAll}
          onPress={() => {
            category("전체보기"); 						
          }}
        >
          <Text style={styles.middleButtonTextAll}>전체보기</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.middleButton01}
          onPress={() => {
            category("생활");
          }}
        >
          <Text style={styles.middleButtonText}>생활</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.middleButton02}
          onPress={() => {
            category("재테크");
          }}
        >
          <Text style={styles.middleButtonText}>재테크</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.middleButton03}
          onPress={() => {
            category("반려견");
          }}
        >
          <Text style={styles.middleButtonText}>반려견</Text>
        </TouchableOpacity>
      </ScrollView>
      <View style={styles.cardContainer}>
        {cateState.map((content, i) => {
          return <Card content={content} key={i} navigation={navigation} />
        })}
      </View>
    </ScrollView>
  );
}

 

이것과 같은 경우, 무조건 data의 category의 단어와 category()함수와 함께 넘어가는 단어가 틀린 것 없이 일치해야 한다는 단점이 있었다.

 

cate로 넘어가는 "반려견"과 data.json에 있는 category의 "반려견"이 똑같아야 반려견 리스트를 불러오게 된다.

cate로 "반려"를 넘기면 아무 리스트도 불러오지 못했다.

 

나는 수업자료같이 딱딱 필요한 데이터가 구분되어 있는 정형화된 자료가 아니고 그냥 막자료(?)를 가지고 해보는거라 반드시 같은 단어가 아니고 특정 단어가 포함되어 있는 데이터를 찾아야 했다. ㅠㅠ 

 

 

 

 

stackoverflow에서 나와 비슷한 고민을 하고 있는 분의 질문을 찾았다. 

https://stackoverflow.com/questions/51085097/check-if-a-string-contains-another-string-react-native

 

 

이 분도 data에서 approvalVariable이 포함된 것만 필터링한 것을 보고싶다는 건데 안 된다는 거다.

거기에 대한 답변은 이거였다.

let filteredData = data.filter(x => String(x.approval).includes(approvalVariable));

!!!  와 나 include로 겁나 해봤는데 안 되던데.. 저 String으로 바꾼 다음에 includes를 써야 했던 거다.

문제는 array object에서 includes를 호출해서 속성을 찾았기 때문이라는데..????

 

 

 

사실 자바스크립트는 쥐약이라...  사용법을 숙지하기 위해 공식문서를 찾아 봤다. 그런데 두 가지가 있넹?

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

 

 

 

1) Array.prototype.includes()

배열이 특정 요소를 포함하고 있는지 판별하고, 결과를 true/false로 반환한다.

구문

arr.includes(valueToFind[, fromIndex])

 

매개변수

valueToFind

 

 

 

2) String.prototype.includes()

하나의 문자열이 다른 문자열에 포함되어 있는지를 판별하고, 결과를 true/false로 반환한다.

 

구문

str.includes(searchString[, position])

매개변수

searchString

 

 

 

 

 

 

음 초보의 입장으로 얼추 봐서는..

Array.includes()는 배열에서 특정 요소를 포함하고 있는지를 확인하는 거라 찾고자 하는 요소(valueToFind)가 반드시 배열(arr) 안에 존재해야 되는 것 같고..

String.includes()는 찾고자 하는 문자열(searchString)이 문자열(str)에 포함되어 있는지를 찾는 것이기 때문에,

내가 써야 하는 기능은 String.includes()였고 그래서 아래처럼 써야 원하는 데이터를 얻을 수 있다는 것!!

let filteredData = data.filter(x => String(x.approval).includes(approvalVariable));

 

 

 

 

 

그래서 완성된 코드는 이렇다.

  const [state, setState] = useState([]);
  const [ready, setReady] = useState(true);
  const [cateState, setCateState] = useState([]);

  useEffect(() => {
    setTimeout(() => {
      setState(data.center_info);
      setCateState(data.center_info);
      setReady(false);
    }, 1000);
  }, []);
  
  const category = (cate) => {
    if (cate == "서울") {
      setCateState(
        state.filter((d) => {
          return String(d.location).includes("서울");
        })
      );
    } else if (cate == "부산") {
      setCateState(
        state.filter((d) => {
          return String(d.location).includes("부산");
        })
      );
    }
  };
  
  return ready ? (
    <Loading />
  ) : (
    <View style={styles.container}>
      <View style={styles.localView}>
        <Text style={styles.localSi}>대전광역시</Text>
        <Text style={styles.localGu}>유성구</Text>
        <TouchableOpacity style={styles.likeButton}>
          <Text style={styles.buttonText}>My 찜</Text>
        </TouchableOpacity>
      </View>
      <ScrollView
        style={styles.buttonContainer}
        horizontal
        indicatorStyle={"white"}
      >
        <TouchableOpacity style={styles.middleButton04}>
          <Text style={styles.middleButtonText}>전체</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.middleButton01}
          onPress={() => {
            category("서울");
          }}
        >
          <Text style={styles.middleButtonText}>서울</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.middleButton02}
          onPress={() => {
            category("부산");
          }}
        >
          <Text style={styles.middleButtonText}>부산</Text>
        </TouchableOpacity>
     </ScrollView>
    </View>
  );
}

1) 서울버튼과 부산버튼에 onPress 화살표 함수를 달아 category를 각각 "서울"과 "부산"으로 정해준다.

2) 위에 const category()함수로 와서 받아온 cate가 해당 data의 location에서  "서울"과 "부산"이 포함되어 있는 데이터만 필터링해서 리스트업해준다.

 

 

데이터양이 너무 많아서 좀 느리긴 하지만 그래도 서울하고 부산이 포함되어 있는 거 잘 찾아온다!!! 아자!!! 이제 다음 단계!!

반응형

댓글