[TIL] React Native에서 useReducer 실습 <2>

Simple Key·2020년 6월 9일
0
post-thumbnail
post-custom-banner

1. useReducer로 rgb(0,0,0) 바꾸기

버튼을 클릭하면 컬러를 진하게 또는 연하게 하도록 state를 관리하기


  1. 먼저 버튼 컴포넌트를 만든다
// ColorCounter 컴포넌트
import React from 'react';
import {View, Text, Button, StyleSheet} from 'react-native';

const ColorCounter = ({color, onIncrease, onDecrease}) => {
  return (
    <View>
      <Text>{color}</Text>
      <Button title={`Increase ${color}`} onPress={onIncrease} />
      <Button title={`Decrease ${color}`} onPress={onDecrease} />
    </View>
  );
};

export default ColorCounter;

  1. ColorCounter 컴포넌트를 이제 SquareScreen 컴포넌트에서 불러온다.
// SquareScreen 컴포넌트
import React, {useReducer} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import ColorCounter from '../components/ColorCounter';

const COLOR_INCREMENT = 15;

// 1. reducer 정의하기
const reducer = (state, action) => {
  switch(action.type){
    case 'change_red' :
      return {...state, red: state.red + action.payload};
    case 'change_green' :
      return {...state, green: state.green + action.payload};
    case 'change_blue' :
      {...state, blue: state.blue + action.payload};
    default :
      return ;
  }
}

// 2. SquareScreen 컴포넌트 정의
const SquareScreen = () => {
  const [state, dispatch] = useReducer(reducer, {red:0, green:0, blue:0})
  const {red, green, blue} = state; // 비구조화 할당
  return(
    <View>
      // 3. ColorCounter 컴포넌트 3개를 불러온다.
      // 3-1. props로 이벤트 핸들러와 컬러를 전달해준다.
      <ColorCounter onIncrease={()=>{}} onDerease={()=>{}} color='red' />
      <ColorCounter onIncrease={()=>{}} onDerease={()=>{}} color='green'  />
      <ColorCounter onIncrease={()=>{}} onDerease={()=>{}} color='blue' r />
      // 4. ⬇︎컬러를 보여줄 View 태그
      <View 
        style={{height:150, weith: 430, backgroundColor: `rgb(${red},${green},${blue})`}} 
      />
      <Text>현재 컬러: --> RGB({`${red},${green},${blue}`})</Text>
    </View>
  )
}

  1. 이제 <ColorCounter /> 컴포넌트 안에 dispatchprops로 넘겨 주어야 한다.
// ----------위 생략----------

    <View>
      <ColorCounter 
        onIncrease={()=>{dispatch({type:'change_red', payload: COLOR_INCREMENT})}} 
        onDcerease={()=>{dispatch({type:'change_red', payload: -1*COLOR_INCREMENT})}} 
        color='red' 
      />
      <ColorCounter 
        onIncrease={()=>{dispatch(type:'change_greed', payload: COLOR_INCREMENT})} 
        onDcerease={()=>{dispatch(type:'change_green', payload: -1*COLOR_INCREMENT})} 
        color='green'
      />
      <ColorCounter 
        onIncrease={()=>{dispatch(type:'change_blue', payload: COLOR_INCREMENT})} 
        onDcerease={()=>{dispatch(type:'change_blue', payload: -1*COLOR_INCREMENT})} 
        color='blue' 
      />
      <View 
        style={{height:150, weith: 430, backgroundColor: `rgb(${red},${green},${blue})`}} 
      />
      <Text>현재 컬러: --> RGB({`${red},${green},${blue}`})</Text>
    </View>

// ----------아래 생략----------

이렇게 해당 컬러마다 '진하게', '연하게' 버튼을 누를때마다 dispatch 함수에 인자로 action을 담아 reducer 함수에 전달하고 reducer함수는 새로운 state 를 리턴한다.


  1. rgb(0, 0, 0)내 숫자 범위는 0부터 255 까지이기 때문에 0보다 작아지거나 255보다 커지지 않도록 reducer 안에 switch 문에서 삼항연산자로 validation 을 추가해준다.
const reducer = (state, action) => {
  switch(action.type){
    case 'change_red' :
      return state.red + action.payload > 255 || state.red + action.payload < 0
      ? state
      : {...state, red: state.red + action.payload};
    case 'change_green' :
      return  state.green + action.payload > 255 || state.green + action.payload < 0
      ? state
      : {...state, green: state.green + action.payload};
    case 'change_blue' :
      return  state.blue + action.payload > 255 || state.blue + action.payload < 0
      ? state
      : {...state, blue: state.blue + action.payload};
    default :
      return ;
  }
}
profile
프론트엔드 개발자 심기현 입니다.
post-custom-banner

0개의 댓글