인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

오영택님의 프로필 이미지
오영택

작성한 질문수

[2024] 비전공자도 가능한 React Native 앱 개발 마스터클래스

기능 만들기

계산기 앱 착오를 거친 수정버전

해결된 질문

작성

·

77

·

수정됨

2

제가 설치를 이상하게 했는지, 잘 되지 않아 저는 프로젝트 생성을 다음과 같은 절차로 진행했습니다.

  1. npx create-expo-app <앱 이름> --template

  2. 세 번째(blank) :typescript 선택

  3. npx expo start를 실행

  4. expo 앱에서 QR 코드로 보기

위와 같은 절차를 거쳐, 복붙으로도 진행해봤을 때의 문제점은 안드로이드 기준으로 기호들이 나타나지 않는다는 점이었습니다. 무지성으로 복붙한 것이 문제였는데요. 문제는 margin 값들의 값이 컸기 때문이었습니다.

 

혹시 저 같이 잘 안 되시는 분들이 있을까 하여, 좀 헤맸던 기록으로 남깁니다~

 

ps. 아래 별도로 올려주신 코드 중에 const [result, setResult] = useState('') 에서 useState('0')으로 변경이 필요합니다.

 

그리고 알려주신 코드를 복붙해서 했을 때 제대로 나오지 않아, GPT의 도움을 받아 수정해보았습니다.

import React, { useState } from 'react';
import { Text, View } from 'react-native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Entypo from 'react-native-vector-icons/Entypo';
import FontAwesome6 from 'react-native-vector-icons/FontAwesome6';
import styled from 'styled-components/native';
import { evaluate } from 'mathjs';

const NumberButton = styled.TouchableOpacity`
  background-color: #b6b6b6;
  width: 65px;
  height: 65px;
  border-radius: 35px;
  margin: 8px;
  align-items: center;
  justify-content: center;
`;

const OperatorButton = styled(NumberButton)`
  background-color: #0084ff;
`;

const NumberText = styled.Text`
  font-size: 30px;
  color: white;
`;

const ResultText = styled.Text`
  font-size: 65px;
  padding: 20px;
  margin-top: 50px;
  color: white;
  text-align: right;
`;

const App = () => {
  const [input, setInput] = useState('');
  const [result, setResult] = useState('0');

  const handlePress = (value) => {
    const newInput = input + value;
    setInput(newInput);
    setResult(newInput); // 입력값을 바로 결과창에 표시
  };

  const handleOperation = (op) => {
    if (input && !['+', '-', '*', '/'].includes(input.slice(-1))) {
      const newInput = input + op;
      setInput(newInput);
      setResult(newInput); // 연산자도 바로 결과창에 표시
    }
  };

  const calculate = () => {
    try {
      const calculatedResult = evaluate(input).toString();
      setResult(calculatedResult);
      setInput(calculatedResult); // 계산 결과를 새로운 입력값으로 설정
    } catch (e) {
      setResult('Error');
      setInput('');
    }
  };

  const clear = () => {
    setInput('');
    setResult('0');
  };

  return (
    <View style={{ flex: 1, backgroundColor: '#181818' }}>
      <ResultText>{result}</ResultText>

      <View style={{ flex: 1, justifyContent: 'flex-end', paddingBottom: 20 }}>
        <View style={{ flexDirection: 'row', justifyContent: 'center' }}>
          <View style={{ paddingRight: 20 }}>
            <View
              style={{ flexDirection: 'row', flexWrap: 'wrap', width: 250 }}
            >
              {[...Array(10).keys()].reverse().map((num) => (
                <NumberButton
                  key={num}
                  onPress={() => handlePress(num.toString())}
                >
                  <NumberText>{num}</NumberText>
                </NumberButton>
              ))}
              <NumberButton onPress={clear}>
                <MaterialIcons name="restart-alt" size={30} color="white" />
              </NumberButton>
              <NumberButton onPress={() => handlePress('.')}>
                <Entypo name="dot-single" size={30} color="white" />
              </NumberButton>
            </View>
          </View>

          <View style={{ marginTop: -81 }}>
            <OperatorButton onPress={calculate}>
              <MaterialCommunityIcons name="equal" size={30} color="white" />
            </OperatorButton>
            <OperatorButton onPress={() => handleOperation('+')}>
              <Entypo name="plus" size={30} color="white" />
            </OperatorButton>
            <OperatorButton onPress={() => handleOperation('-')}>
              <Entypo name="minus" size={30} color="white" />
            </OperatorButton>
            <OperatorButton onPress={() => handleOperation('*')}>
              <Entypo name="cross" size={30} color="white" />
            </OperatorButton>
            <OperatorButton onPress={() => handleOperation('/')}>
              <FontAwesome6 name="divide" size={30} color="white" />
            </OperatorButton>
          </View>
        </View>
      </View>
    </View>
  );
};

export default App;

답변 2

1

정현우님의 프로필 이미지
정현우
지식공유자

코드 수정 너무 감사드립니다 오영택님!

강의 영상 차원에서 수강생분들이 더 코드에 잘 접근하실 수 있도록 항상 신경쓰고 개선해 나가도록 하겠습니다. 소중한 의견 너무 감사드립니다.

오영택님의 프로필 이미지
오영택
질문자

답변 감사합니다~

여러 글들에 하나하나 답변 달아주시는 것들 보면서 계속해서 개선해나가시는 것을 봤습니다. 좋은 강의 감사드립니다!

정현우님의 프로필 이미지
정현우
지식공유자

ㅜㅜㅜ 아닙니다 수강생님 많이 부족한 강의인데도 지속적으로 관심 가져주셔서 너무 감사드리고 수강생님같은 분들 덕분에 힘들 얻는 것 같습니다. 너무 감사드려요 오영택님

앞으로도 더 개선해나가고 열심히 하는 지식공유자가 되도록 하겠습니다. 진심으로 감사드립니다 :)

0

안녕하세요, 인프런 AI 인턴입니다. 오영택님.

React Native 환경에서 앱을 설치하고 프로젝트를 설정하는 과정에서 발생한 문제와 해결 방법을 공유해주셔서 감사합니다. 주어진 코드와 절차에 대해 몇 가지 코멘트를 드리겠습니다.

프로젝트 생성 절차

오영택님께서 공유해주신 절차는 Expo로 환경을 설정하는 방법 중 하나입니다. 아래는 전체적인 절차에 대한 요약입니다:

  1. npx create-expo-app <앱 이름> --template 명령어를 사용해 Expo 프로젝트를 생성합니다. 이때, “blank” 템플릿을 선택하셨습니다.
  2. npx expo start 명령어로 프로젝트를 시작하고 실행합니다.
  3. Expo 앱을 사용하여 QR 코드를 스캔하여 앱을 실행하셨습니다.

코드 수정 부분

사용자 경험에 따라 프로젝트의 표현이 달라질 수 있습니다. 특히, 스타일이나 레이아웃 측면에서 수정이 필요할 수 있습니다. 기호가 Android에서 제공되지 않는 문제는 react-native-vector-icons의 설정을 살펴보시는 것도 좋습니다.

  • useState('0')로의 변경: 초기 값으로 문자열 ‘0’을 설정하여 결과가 기본적으로 ‘0’으로 나타나도록 하는 부분은 적절합니다.
  • react-native-vector-icons 라이브러리: 벡터 아이콘 사용 시 Android에서는 특정 설정이 필요할 수 있습니다. 관련 공식 문서에서 설정 방법을 확인하시기 바랍니다.

또한, 아래의 관련 질문들에서도 비슷한 문제에 대한 토론이 있습니다:

  1. expo로 설치해도 되나요?

    • 내용 요약: Expo를 사용한 설치와 리액트 네이티브 설정 방법에 대해 언급된 부분입니다.
  2. 프로젝트 생성에 대해서?

    • 내용 요약: Expo를 사용하지 않은 프로젝트 생성 방법에 대한 설명입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

오영택님의 프로필 이미지
오영택

작성한 질문수

질문하기