본문 바로가기
Hybrid/React Native

리액트 네이티브] 4. props

by 김마리님 2021. 10. 5.

1. props 

props는 부모 컴포넌트로부터 자식 컴포넌트에게 전달 혹은 상속되는 속성값을 말한다. 이 값은 자식 컴포넌트에서 활용은 가능하지만 수정은 불가하다. 이 값의 변경이 필요하다면 반드시 부모에서 변경해야만 한다.

props 전달 예시를 보자.

 

- ../src/App.js

import React from "react";
import { View, Text, Button } from "react-native";
import MyButton from "../component/myButton";

const App = () => {
    return (
        <View style={{
            flex: 1,
            backgroundColor: '#fff',
            alignItems: 'center',
            justifyContent: 'center',
          }}>
            <Text style={{fontSize : 30, marginBottom : 10}}>Button Component</Text>
            <MyButton title="Button"/>
          </View>
    );
}

export default App;

 

-../component/myButton.js

import React from "react";
import { Pressable, Text, TouchableOpacity } from "react-native";

const MyButton = props => {
    console.log(props);
    return (
        <Pressable
        style = {{
            backgroundColor : '#aaaaaa',
            padding : 16,
            margin: 10,
            borderRadius : 5,
        }}
        onPress = {() => alert("click")}>
            <Text style={{fontSize : 24, color : '#ffffff'}}>Button</Text>
        </Pressable>
    );
};

export default MyButton;

App.js에서  myButton를 호출할 때, title속성을 보냈다. 

이 부분을 myButton 컴포넌트 함수에서 이 속성을 전달 받을 수 있다. 예시 코드에서는 이 속성을 콘솔로 확인한다.

이 콘솔 로그는 터미널에서 확인 가능한데, 한번 확인해보자.

 

 

이제 이 값을 실제 버튼으로 출력해보자.

확인을 위해 버튼의 title값을 props title로 변경하자.

 

- ../src/App.js

...
<MyButton title="Props Button"/>
...

 

이 값을 버튼에 실제로 적용해보자.

-../component/myButton.js

...
<Text style={{fontSize : 24, color : '#ffffff'}}>{props.title}</Text>
...

 

버튼의 텍스트가 props title 속성으로 변경된 것이 보인다.

 

 

2. children

props를 전달하는 방식이 하나 더 있는데, 태그 내부에 값을 넣으면 props.children으로 참조할 수 있다.

 

- ../src/App.js

            <MyButton title="Props Button"/>
            <MyButton title="Props Button">Children props</MyButton>

-../component/myButton.js

            <Text style={{fontSize : 24, color : '#ffffff'}}>{props.children||props.title}</Text>

 

해당 코드는 props.children이 있다면 props.children을 출력하는 코드이다. 

결과를 보자.

children props가 출력된 것이 보인다.

 

3. default props

만일 이 props를 전달하지 않으면 어떻게 될까?

- ../src/App.js

...
            <Text style={{fontSize : 30, marginBottom : 10}}>Button Component</Text>
            <MyButton title="Props Button"/>
            <MyButton title="Props Button">Children props</MyButton>
            <MyButton></MyButton>
            ...

당연하게도 props값이 없어 전달되는 값이 없으므로 빈 값이 전달된다.

 

그러나 값을 입력하지 않을 때의 값을 고정하고 싶을 때가 있다. 그럴 때 사용하는 것이 defaultProp이다. 값을 전달받기 전까지 디폴트 값을 정해두는 방식이다.

 

이것은 디폴트 컴포넌트의 아래에 선언해주면 된다.

 

-../component/myButton.js

const MyButton = props => {
    ...
};

MyButton.defaultProps = {
    title : "Default Props",
}

 

위에 기술한 ../src/App.js는 변경하지 않고 Refreshing만 해주었다. 결과를 보자.

 

 

4. propType

프로젝트의 크기가 커지거나, 다인개발의 경우 props의 전달이 잘못되는 경우가 있다(안드 개발해보신 분이면 액티비티에서 값 넘길때 생각하시면 될듯 ^-ㅠ) 이런 상황에서 전달에 대한 규제를 거는 방법이 있는데, 그것이 propType이다.

propType은 npm라이브러리에서 제공한다.

 

npm install prop-types

 

해당 명령어를 터미널에 입력하면 자동으로 npm 업데이트가 일어난다.

이제 타입의 제약을 걸어본다.

 

해당 라이브러리를 임포트 하고

import PropTypes from 'prop-types';

 

제약을 걸어보자.

 

-../component/myButton.js

const MyButton = props => {
     ...
};

MyButton.propTypes = {
    title : PropTypes.number,
}

 

이후에 Refresh해보면 앱이 정상작동하긴 하는데, 경고가 뜬다.

Warning: Failed prop type: Invalid prop `title` of type `string` supplied to `MyButton`, expected `number`.

숫자로 와야할 prop들이 문자로 왔다는 것을 경고하는 메세지이다.

 

따라서, 다음과 같이 변경되어야 한다.

-../component/myButton.js

const MyButton = props => {
     ...
};

MyButton.propTypes = {
    title : PropTypes.string,
}

 

또한 필수여부도 지정할 수 있는데,

-../component/myButton.js

const MyButton = props => {
     ...
};

MyButton.propTypes = {
    title : PropTypes.string,
    obj : PropTypes.string.isRequired,
}

props앞에 isRequired를 입력하면 해당 값이 없을 경우 다음과 같은 경고 안내문이 출력된다. 필수 출력되야하는 값이 출력되지 않았기 때문이다.

Warning: Failed prop type: The prop `obj` is marked as required in `MyButton`, but its value is `undefined`.

그런데 또 자세히 보면 title에 대한 경고는 없는데, isRequired되지 않았기 때문에 값이 빠져도 상관하지 않는 것이다. 

(근데 이건 안드로이드 Expo Go에선 출력되지 않는 문제더라고요?)

 

또한 이벤트 리스너도 요구할 수 있는데, 다음과 같이 컴포넌트 값과 App.js를 변경해보자.

 

-../component/myButton.js

const MyButton = props => {
     ...
};

MyButton.defaultProps = {
    title : "Default Props",
}

MyButton.propTypes = {
    title : PropTypes.string,
    onPress : PropTypes.func.isRequired,
}

 

- ../src/App.js

...
            <Text style={{fontSize : 30, marginBottom : 10}}>Button Component</Text>
            <MyButton title="Props Button" onPress={()=>alert('properties')}/>
            <MyButton title="Props Button" onPress={()=>alert('children')}>Children props</MyButton>
            <MyButton onPress={()=>alert('default')}></MyButton>
            ...

 

결과는 다음과 같다.

 

 

반응형