[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

b0-0d