logo
|
Blog

    [RN] 구문 내 제각각 위치의 포인트 컬러를 가지는 텍스트 프롭으로 받아 렌더해주기

    💪효율적으로 스크린 그리는 방법 찾아가기
    김보람's avatar
    김보람
    May 29, 2025
    [RN] 구문 내 제각각 위치의 포인트 컬러를 가지는 텍스트 프롭으로 받아 렌더해주기

    어떻게 그릴래?

    • 상황

      • 컴포넌트의 폼은 같고, 텍스트만 아이템들만 다르기에 텍스트만 Prop으로 받아 렌더링 하고 싶음

        위 같은 형태일때 사실 박스가 몇개 되지 않느다면 그냥 그리는게 훨씬 빠르다. 하지만 박스가 많아질 경우 굳이 똑같은 코드를 쓸 필요가 없이 때문에 ✓텍스트 아이템을 프롭으로 받기로 한다.

    • 고민

      • 텍스트아이템 내에 포인트 컬러가 존재하고 포인트 컬러를 가지는 텍스트의 위치는 제각각 이기때문에 동적으로 받을 수 있어야한다

      • 아래 처럼 엘리먼트 자체를 칠드런으로 받아도 되긴된다. 그렇게 되면 재사용하는데 한계가 있고, 지금 내 기모찌가 용납하지 않는다.

        <RichText>
          <Text>
            <Text>노말</Text>
            //이게싫음 컬러를 각각 주는 것이 싫음
            <Text color={pointcolor}>포인트</Text>
            <Text>노말</Text>
          </Text>
        </RichText>

    • 시도한 방법 (좋은 방법이 생각나면 또또또바꿀꺼임)

      • 아래처럼 받아서 highlight가 있으면 요것은 포인트 컬러

        [
            {
              segments: [
                { text: '데이터 이용 시, 서비스 이용 중 ' },
                { text: '데이터 통신요금', highlight: true },
                { text: '이 발생할 수 있어요.' },
              ],
            },
            
          ]

      • 즉! 정리하면

        • 이러한 데이터형태를 만들고 “ lines”만 보세여 (파일분리 필수)

            const statusList: statusListType = [
              {
                id: '1',
                icon: IMAGES.BATTERY_ICON,
                name: 'Battery',
                title_ko: '배터리',
                lines: [
                  {
                    segments: [
                      {text: '90% 이상 ', highlight: true},
                      {text: '충전 상태를 권고해요.'},
                    ],
                  },
                ],
                component: StatusBox,
              },
              {
                id: '2',
                icon: IMAGES.NETWORK_ICON,
                name: 'Network',
                title_ko: '네트워크',
                lines: [
                  {
                    segments: [
                      {text: '데이터 이용 시, 서비스 이용 중 '},
                      {text: '데이터 통신요금', highlight: true},
                      {text: '이 발생할 수 있어요.'},
                    ],
                  },
                  {
                    segments: [
                      {text: '서비스 이용 중 App이 중단되지 않도록 '},
                      {text: '원활한 네트워크 상태', highlight: true},
                      {text: '인지 확인해 주세요.'},
                    ],
                  },
                ],
                component: StatusBox,
              },
          
              {
                id: '3',
                icon: IMAGES.STORAGE_ICON,
                name: 'Storage',
                title_ko: '저장용량',
                lines: [
                  {
                    segments: [
                      {
                        text: '갤러리 사진과 동영상을 지운 뒤 휴지통을 비우거나 사용하지 않는 앱을 정리해 ',
                      },
                      {text: '4GB 이상의 저장공간', highlight: true},
                      {text: '을 확보해주세요.'},
                    ],
                  },
                ],
                component: StatusBox,
              },
              {
                id: '4',
                icon: IMAGES.VOLUME_ICON,
                name: 'Volume',
                title_ko: '사운드',
                component: StatusBox,
              },
            ];

        • 이렇게 받아쓴다

          <RichText key={statusData.id} textItem={statusData.lines} />

        • RichText요친구는 아래와 같이 생김

          
          // 이 포스팅에선 다른건 볼필요가 없음
          // 요고보셈 color={seg.highlight ? MAIN_COLOR.blue : undefined} 
          // 위에 제시한 형태의 textItem를 받아서 highlight가 ture면
          // blue로 렌더
          
          const RichText = (items: {key: string; textItem: linesType}) => {
            return (
              <View style={{justifyContent: 'center'}}>
                {items.textItem?.map((line, idx) => {
                  return (
                    <View
                      style={{
                        flexDirection: 'row',
                        alignItems: 'flex-start',
                        paddingBottom: items.textItem.length > 1 ? 16 : 0,
                      }}
                      key={idx}>
                      <LocalImage source={IMAGES.CHECK_BLUE_1} size={20} />
                      <Spacer horizontal space={4} />
                      <Text style={{flexShrink: 1}}>
                        {line.segments.map((seg, idx_) => {
                          return (
                            <Typography
                              key={idx_}
                              color={seg.highlight ? MAIN_COLOR.blue : undefined}
                              style={B_12}
                              lineHeight={20}>
                              {seg.text}
                            </Typography>
                          );
                        })}
                      </Text>
                    </View>
                  );
                })}
              </View>
            );
          };

    Share article

    김보람 | 930802qhfka@gmail.com

    RSS·Powered by Inblog