[React]별점(Star Rating) 기능 구현 (React + Typescript)

2021. 1. 8. 02:11React, Javascript

반응형

 

개요

 

별점을 주는 기능은 매우 흔하게 쓰이는 컴포넌트지만 구현하기는 꽤 까다로운 기능이다.

 

마우스를 별에 가져가면 별점이 자동으로 올라가게 만들거나, 클릭을 통해 별점을 지정하는 등 다양하게 만들 수 있다.

 

React에는 react-star-rating-component

 

react-star-rating-component

React component for star (or any other icon based) ratings

www.npmjs.com

위와 같은 라이브러리가 있다.

 

하지만 Typescript를 지원하지 않아서 React + Typescript 프로젝트를 진행하거나 간단한 구현을 원한다면 이 포스팅을 참고 하시길 바란다.

 

 

 

Html 요소

 

별점을 나타내는 html 요소에는 많은 방법이 있다. 실제 이미지를 만들어서 사용해도 되고 svg를 활용해도 된다.

 

필자는 간단한 기능 구현을 위해 <i>태그를 활용하겠다.

 

<i className='item-rating pointer zmdi zmdi-star'>  <!-- 채워진 별 -->

<i className='item-rating pointer zmdi zmdi-star-outline'>  <!-- 빈 별 -->

 

 

동작 원리

 

필요한 화면 요소를 구했으니 이제 이것을 동적으로 잘 바꾸기만 하면 된다.

 

마우스 오버나 클릭시에 html의 className을 변하게 하면 되는 것이다.

 

그러기 위해서는 className을 State로 관리하는 것이 좋아 보인다.

 

 

별점의 만점을 몇 점으로 할 것인지 정해서 마우스 오버나 클릭이라는 이벤트가 일어나면 해당 수만큼 반복문을 이용하면 별점 기능을 구현할 수 있을 것이다.

 

 

 

소스 코드

 

별다른 미들웨어들을 쓰지 않고 기본적인 React 컨포넌트와 반복문, 조건문을 사용하여 구현해 보겠다.

 

여기에 필요에 따라 라이브러리를 추가하여 더 세부적인 기능 구현을 하면 되겠다.

 

import React, { ReactElemnet, useEffect } from 'react'    //필요 library import



const StarRating : React.FC = ():ReactElement => {

// 별점을 className을 관리할 배열 변수를 type을 정해서 선언한다.
  let starRatingState : Array<string> = []

// 별점 className을 state로 관리하기 위해 useState를 사용해 state를 선언한다.
  const [starRatingOnOff, setStarRatingOnOff] = React.useState(starRatingState)


//mouseOver시 호출될 function 정의
  function mouseOverStarRating( inx : number ){
     let tempStarRating : Array<string> = []
     for( let i =0; i< 5; i++ ){
        if( i < inx ){
            //inx보다 앞에 있는 별은 모두 채워지게 한다.
        	tempStarRating.push( 'item-rating pointer zmdi zmdi-star' )
        }else{
            //inx보다 뒤에 있는 별은 빈 상태로 놔둔다.
        	tempStarRating.push( 'item-rating pointer zmdi zmdi-star-outline' )
        }
     }
     setStarRatingOnOff(tempStarRating) //새로운 state를 세팅한다.
  }



// 화면이 렌더링 될때 먼저 수행하기 위해 useEffect를 사용한다.
  useEffect(() => {
    //5점 만점으로 처음에는 별이 다 빈 상태임으로 5개를 모두 outline으로 만든다.
    for( let i =0; i< 5; i++ ){
    	starRatingState.push( 'item-rating pointer zmdi zmdi-star-outline' )
    }
    setStarRatingOnOff(starRatingState)

  },[])

  return (
     <i className={starRatingOnOff[0]} onMouseOver={()=>mouseOverStarRating(0)} />
     <i className={starRatingOnOff[1]} onMouseOver={()=>mouseOverStarRating(1)} />
     <i className={starRatingOnOff[2]} onMouseOver={()=>mouseOverStarRating(2)} />
     <i className={starRatingOnOff[3]} onMouseOver={()=>mouseOverStarRating(3)} />
     <i className={starRatingOnOff[4]} onMouseOver={()=>mouseOverStarRating(4)} />
  )
}

 

마우스 오버에 따라 별점이 움직이는 React 컴포넌트를 완성했다.

 

클릭시 별점이 부여되게 하려면 html i 태그에 있는 onMouseOver함수를 onClick으로 바꾸면 된다.

 

두가지를 모두 넣고 싶으면 모두 선언해 주면 된다.

 

여기에 최종 부여된 별점이 몇 점인지 관리 하는 state를 만들어 서버에 저장할때 보내주면 된다.

 

 

간단한 별점 기능을 구현해 보았다.

 

 

반응형