본문 바로가기

TIL

[TIL-159] React Native

전역 상태 관리의 필요성

point와 카드 번호를 홈 화면과 송금 화면 두 스크린에서 필요한 상황이다. 지금은 각 화면에 도착했을 때, useEffect를 사용하여 컴포넌트가 최초 렌더링 된 직후에만 요청을 보내 두 가지 값을 받아왔다. 그런데 홈에서 송금 화면으로 스크린을 이동했을 때 그 사이 point 잔액이 바뀌어서 새로운 값을 받게 되었다. 이때 송금 화면에서 뒤로가기 버튼을 눌러 홈화면으로 넘어오면, "뒤로가기" 때문인지 화면이 새로고침되지 않아서 point와 카드번호를 받아오는 요청이 보내지지 않는다. 그래서 변경 전 point 잔액이 여전히 그려지는 문제가 있다.

point를 전역 state로 관리함으로써, 요청을 보내서 값이 변경될 때마다 하나의 state에 저장하면 된다. 화면(컴포넌트)에 관계 없이 하나의 "point" state를 사용하면, 다른 화면에서 state 값이 바뀌었어도 뒤로가기 하여 돌아왔을 때 화면을 다시 렌더링할 것이다.

 

 

 

 

flexColumn: "row"에서 가운데를 기준으로 좌우 대칭 정렬이 안될 때

문제: spaceBetween

<View style={{ flexColumn: "row", justifyContent: 'space-between', alignItems: 'center' }}>
	<View style={{ width: '20%' }></View>
	<Text style={{ width: '30%' }}>{headerText}</Text>
	<View style={{ width: '20%',  alignItems: 'flex-end' }></View>
</View>

 

 

해결: flex

<View style={{ flexColumn: "row", alignItems: "center" }}>
	<View style={{ flex: 1 }></View>
	<Text style={{ flex: 3, textAlign: "center" }}>{headerText}</Text>
	<View style={{ flex: 1,  alignItems: 'flex-end' }></View>
</View>

 

 

 

 

그림자 넣기

안드로이드

import { View, Image, Platform } from 'react-native';

<View
    style={{
      backgroundColor: 'white',
      borderRadius: 5,
      ...Platform.select({
        android: {
          elevation: 3,
        },
      }),
    }}>
    <Image
      source={require('../../assets/example.png')}
    />
</View>

그림자를 넣는 방법은 안드로이드와 ios가 다르다. 그래서 Platform을 import 해준 뒤에 style에서 플랫폼에 따라 다르게 지정해줘야한다. 웹과 완전히 같게 할 수는 없지만, ios는 그나마 사용할 수 있는 속성이 다양하다. 하지만 안드로이드는 제한적이라서 elevation 밖에 쓸 수 없다. 그래서 다양한 그림자 스타일을 원하거나, 플랫폼에 따라 각각 설정하는 것이 싫다면 react-native-shadow-2 같은 라이브러리를 사용해야 한다.

https://blog.pumpkin-raccoon.com/121?category=1062972 

 

 

 

 

상태바(StatusBar) 스타일 바꾸기

// 글자는 하얀색, 배경은 투명(화면이 그리는 배경이 뒤에 깔림)
<StatusBar backgroundColor={'transparent'} translucent={true} />

// 글자는 까만색, 배경은 투명(화면의 배경이 상태바 영역을 침범하여 올라오지 않음)
<StatusBar barStyle="dark-content" backgroundColor={'transparent'} />

이전 스크린에서 translucent가 true였으면 다음 스크린에서 false라고 값을 바꿔주지 않으면 이어짐??

https://dev-yakuza.posstree.com/ko/react-native/react-native-status-bar/

 

 

 

토큰 전달하기

에러 1 : JSON 파싱 문제

로그인 페이지에서 홈화면으로 이동하기 전에 서버에서 받은 토큰 객체를 JSON.stringify() 메소드를 이용하여 문자열 형태로 변환하여 AsyncStorage에 저장했다. 그런데 꺼내서 쓸 때 JSON.parse() 하여 객체로 바꾸지 않고서 key로 토큰 값을 불러오려고 했다.

 

 

에러 2 : state 업데이트 문제

  const [token, setToken] = useState({});
  const [cash, setCash] = useState('15000');

  console.log(token.access, cash);

  useEffect(() => {
    AsyncStorage.getItem('token').then(value => {
      if (value) {
        console.log(value);
        setToken(JSON.parse(value));
      } else {
        console.log('토큰이 없습니다.');
      }
    });
  }, []);

  useEffect(() => {
    fetch(API.point, {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${token.access}`,
        },
    })
      .then(res => res.json())
      .then(result => {
        console.log(result);
        setCash(result[0].point);
      });
  }, []);

자꾸 유효하지 않은 토큰이라는 에러가 났다. 그런데 이동한 페이지에서 새로고침이 되면 다시 보내지는 요청에서 토큰이 통과됐다. state가 업데이트되기 전에 요청을 보낸 탓인 것 같았다. 전에도 프로젝트를 할 때마다 겪었던 문제이다.

해결 1. 같은 조건의 useEffect가 반복되게 둘 생각은 아니었지만, 일단 동작할 코드가 작성된 후 정리하려고 둔 거였다. 하지만 정리할 때가 온 것 같다.

해결 2. token이라는 state를 만들어서 async storage의 토큰을 불러와 저장하고 꺼내쓰는 방식이 불필요하다. token이 여러 번 쓰이거나 바뀔까봐 저장했는데 진행해보니 그럴 일이 없는 것 같다.

 

 

  const [cash, setCash] = useState('15000');

  useEffect(() => {
    AsyncStorage.getItem('token')
      .then(value => {
        if (value) {
          console.log(value);
          getPoint(JSON.parse(value).access);
        } else {
          console.log('토큰이 없습니다.');
        }
      })
      .then();
  }, []);

  const getPoint = token => {
    fetch(API.point, {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${token}`,
      },
    })
      .then(res => res.json())
      .then(result => {
        console.log(result);
        setCash(result[0].point);
      })
      .catch(error => console.log(error));
  };

해결 1. 

then으로 이어서 코드를 붙이려다가 함수로 따로 뺐다. 그렇게 하면 복잡해서 헷갈리고 작동도 잘 안했다. 이게 보다 명확해보이는 것 같다.

 

...

 


공부할 것

  • react-native-pin-view 등 사용한 라이브러리 소스코드 열어보고 공부하기
  • redux

'TIL' 카테고리의 다른 글

[TIL-161] React Native  (0) 2022.04.08
[TIL-160] React Native  (0) 2022.04.07
[TIL-158] React Native  (0) 2022.04.04
[TIL-157] React Native - 유효성 검사  (0) 2022.04.03
AWS EC2 프리티어 과금  (0) 2022.04.03