본문 바로가기
framework/React Native

React Native(2)

by bluromangames 2022. 5. 12.

리액트네이티브 는 리액트라는 자바스크립트를 사용한 유명한 오픈 소스 라이브러리를 기반으로 동작합니다. 그러므로 리액트네이티브를 보다 잘 이해하기 위해서는 리액트 자체를 이해할 필요가 있습니다. 여기서는 소개하는 정도로 리액트에 대해서 얘기 해 볼까 합니다.

리액트를 이해하기 위해서는 (오역을 피하기 위해 영어를 사용합니다.)

  • components
  • JSX
  • props
  • state

이상 네 가지에 대한 이해가 필요합니다. 

Components

import React, { Component } from 'react';
import { Text } from 'react-native';

class Bird extends Component {
  render() {
    return (
      <Text>Hello, I am your bird!</Text>
    );
  }
}

export default Bird;

리액트로 부터 Component를 임포트 합니다.

import React, { Component } from 'react';

Component로 부터 상속받은 클래스 component를 선언합니다.

class Bird extends Component {}

클래스 component는 render() 함수를 가지고 있습니다. 텍스트를 리턴하고, 리액트 엘리먼트로써 렌더링 됩니다.

class Bird extends Component {
  render() {
    return <Text>Hello, I am your bird!</Text>;
  }
}

함수 component로써, 만들어진 Bird component를 엑스포트 할 수 있습니다.

class Bird extends Component {
  render() {
    return <Text>Hello, I am your bird!</Text>;
  }
}

export default Bird;

위의 리턴을 자세히 보면 <Text>Hello, I am your bird!</Text> 은 자바스크립트로 되어있음을 알 수 있습니다. 리액트에서는 리턴을 위해 JSX를 사용합니다.

JSX

리액트와 리액트네이티브는 JSX를 사용합니다. JSX는 자바스크립트에서 엘리먼트를 나타낼때 사용하는 정해진 형식입니다. JSX가 자바스크립트이므로, 그 안에 변수를 정의 할 수 있습니다. JSX에 대한 보다 자세한 형식은 a comprehensive guide to JSX 를 참고 하도록 합니다. 

import React from 'react';
import { Text } from 'react-native';

const Bird = () => {
  const name = "Maru";
  return (
    <Text>Hello, I am {name}!</Text>
  );
}

export default Bird;

{name} 위치에는 어떠한 자바스크립트라도 올 수 있습니다. 다음과 같은 함수도 포함해서{getFullName("Rum", "Tum", "Tugger")}:

import React from 'react';
import { Text } from 'react-native';

const getFullName = (firstName, secondName, thirdName) => {
  return firstName + " " + secondName + " " + thirdName;
}

const Bird = () => {
  return (
    <Text>
      Hello, I am {getFullName("Rum", "Tum", "Tugger")}!
    </Text>
  );
}

export default Bird;

커스텀 컴포넌트(Custom Component)

리액트 네이티브에 대한 첫 번째 포스트에서 리액트 코어 컴포넌트를 소개 했습니다. 리액트는 컴포넌트가 컴포넌트를 네스팅(nesting)하는 방식으로도 새로운 컴포넌트를 만들 수 있습니다. 이것이 바로 리액트의 패러다임이라고 할 수 있습니다.

예를 들면, 뷰 안에 텍스트와 TextInput을 네스팅 할 수 있고, 리액트 네이티브에서 렌더링 할 수 있습니다.

import React from 'react';
import { Text, TextInput, View } from 'react-native';

const Bird = () => {
  return (
    <View>
      <Text>Hello, I am...</Text>
      <TextInput
        style={{
          height: 40,
          borderColor: 'gray',
          borderWidth: 1
        }}
        defaultValue="Name me!"
      />
    </View>
  );
}

export default Bird;

또한 코드를 다시 쓸 필요 없이 <Bird>를 사용하면 컴포넌트를 여러번 렌더링 할 수도 있습니다.

import React from 'react';
import { Text, View } from 'react-native';

const Bird = () => {
  return (
    <View>
      <Text>I am also a bird!</Text>
    </View>
  );
}

const Cafe = () => {
  return (
    <View>
      <Text>Welcome!</Text>
      <Bird />
      <Bird />
      <Bird />
    </View>
  );
}

export default Cafe;

다른 컴포넌트를 렌더링하는 컴포넌트를 부모(parent) 컴포넌트라고 합니다. 위의 예에서 Cafe는 Bird의 부모 컴포넌트가 됩니다. 

프로퍼티(Props)

Props“properties”의 줄임말 입니다. Props는 리액트 컴포넌트를 커스터마이징 할 수 있도록 합니다.

예를 들면, 같은 <Bird>를 호출하지만 각각의 Bird에 서로 다른 이름을 붙여서 렌더링 할 수 있습니다.

import React from 'react';
import { Text, View } from 'react-native';

const Bird = (props) => {
  return (
    <View>
      <Text>Hello, I am {props.name}!</Text>
    </View>
  );
}

const Cafe = () => {
  return (
    <View>
      <Bird name="Maru" />
      <Bird name="Jellylorum" />
      <Bird name="Spot" />
    </View>
  );
}

export default Cafe;

대부분의 리액트 네이티브의 코어 컴포넌트는 props를 사용하여 커스터마이징 할 수 있습니다.

예를 들면 Image 컴포넌트에서 source라는 prop을 통해서 어떤 이미지를 보여 줄지를 결정 할 수 있습니다.

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

const BirdApp = () => {
  return (
    <View>
      <Image
        source={{uri: "https://reactnative.dev/docs/assets/p_bird1.png"}}
        style={{width: 200, height: 200}}
      />
      <Text>Hello, I am your bird!</Text>
    </View>
  );
}

export default BirdApp;

스테이트(State)

Props를 컴포넌트가 어떤식으로 렌더링할 지에 대한 매개 변수라고 한다면, 스테이트는 컴포넌의 데이터 스토리지라고 할 수 있습니다. 스테이트는 자주 변화하는 데이터나 사용자의 상호작용으로 변화하는 데이터에 유용합니다. 스테이트는 컴포넌트의 메모리라고 할 수 있습니다. 

다음 예제에서는 고양이 cafe에서 두 마리의 배고픈 고양이에게 먹이를 주는 예제 입니다. 고양이 각각의 배고픈 상태가 스테이트로 저장이 되어서 때에 따라서 바꿀 수 있도록 합니다. 고양이에게 먹이를 주기 위해서는 버튼이 필요하고, 버튼을 누르면 각각의 상태가 업데이트 됩니다.

import React, { Component } from "react";
import { Button, Text, View } from "react-native";

class Cat extends Component {
  state = { isHungry: true };

  render() {
    return (
      <View>
        <Text>
          I am {this.props.name}, and I am
          {this.state.isHungry ? " hungry" : " full"}!
        </Text>
        <Button
          onPress={() => {
            this.setState({ isHungry: false });
          }}
          disabled={!this.state.isHungry}
          title={
            this.state.isHungry ? "Pour me some milk, please!" : "Thank you!"
          }
        />
      </View>
    );
  }
}

class Cafe extends Component {
  render() {
    return (
      <>
        <Cat name="Munkustrap" />
        <Cat name="Spot" />
      </>
    );
  }
}

export default Cafe;

중요 부분만 살펴 보면,

클래스 컴포넌트에서 스테이트는 스테이트 오브젝트에 저장 됩니다.

export class Cat extends Component {
  state = { isHungry: true };
  //..
}

this.props를 통하여 props에 접근 가능하므로, 컴포넌트 안에서 this.state를 사용하여 오브젝트에 접근 할 수 있습니다.

<Text>
  I am {this.props.name}, and I am
  {this.state.isHungry ? ' hungry' : ' full'}!
</Text>

스테이트에 대한 키 값을 가진 스테이트 오브젝트 안에서 this.setState()를 통하여 새로운 값을 세팅할 수 있습니다.

<Button
  onPress={() => {
    this.setState({ isHungry: false });
  }}
  // ..
/>

this.state.isHungry값이 false가 되면 버튼의 disabled prop이 true로 세팅되고, 타이틀이 바뀝니다.

<Button
  // ..
  disabled={!this.state.isHungry}
  title={
    this.state.isHungry
      ? 'Pour me some milk, please!'
      : 'Thank you!'
  }
/>

이상으로 리액트와 리액트 네이티브의 기본 적인 컴포넌트들에 대해서 알아 봤습니다. 각각의 컴포넌트에 대한 보다 세밀한 접근은 프로젝트 예제를 사용하여 실전으로 만들어 보는 작업을 할 예정입니다.

'framework > React Native' 카테고리의 다른 글

React Native(1)  (0) 2022.05.12