[react native] Props 완벽 정리

    반응형
    이 글은 <"처음 배우는 리액트 네이티브 (김범준, 한빛미디어)">를 읽고 이해한 바를 바탕으로 작성되었습니다.
    https://github.com/Alchemist85K/my-first-react-native
     

    GitHub - Alchemist85K/my-first-react-native: [한빛미디어] 처음 배우는 리액트 네이티브 소스 코드입니다.

    [한빛미디어] 처음 배우는 리액트 네이티브 소스 코드입니다. . Contribute to Alchemist85K/my-first-react-native development by creating an account on GitHub.

    github.com

    리액트 네이티브에서 가장 기본중의 기본이 되는 구성요소인 Component는 데이터와 UI 구성요소의 집합체로 볼 수 있다. UI는 보여지는 생김새(?)에 해당하고, 데이터는 Component가 가지고 있는 값, 기능에 해당한다고 할 수 있겠다.

     

    중요하다길래 제목에도 별 두개,,,ㅎ⭐

     

    💡 props

    props는 properties가 줄여진 표현이다. 부모 컴포넌트로부터 전달된/상속받은 속성값을 말한다.

    부모 컴포넌트에서 자식 컴포넌트에게 props를 넘기면 자식컴포넌트는 받은 props를 사용할 수는 있지만 변경할 수는 없다. (props의 변경이 필요한 경우는 부모 컴포넌트에서 변경해야 한다.)

     

    ✔️ 예시 코드

    <Button title='Button' />

    Button 컴포넌트에 title 속성을 지정하면, Button 컴포넌트의 props로 title값이 전달된다.

     

    ✔️ App 컴포넌트에서 MyButton 컴포넌트에 title 속성을 입력(props 지정(?))

    import React from "react";
    import { Text, View } from "react-native";
    import MyButton from "./components/MyButton";
    
    const App = () => {
      return (
        <View
          style={{
            flex: 1,
            backgroundColor: "#fff",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Text style={{ fontSize: 30, marginBottom: 10, textAlign: "center" }}>
            My Button Component
          </Text>
          <MyButton title="props" />
        </View>
      );
    };
    
    export default App;

    <MyButton title="props" />에서 MyButton 컴포넌트에 "props"라는 값을 title의 속성값으로 지정해주었다.

    이렇게 하면 App 컴포넌트에서 MyButton 컴포넌트를 호출할 때 title 속성에 "props"라는 문자열을 전달한다.

    자식 컴포넌트(여기서는 MyButton 컴포넌트)에서는 부모로부터 전달된 props를 함수의 파라미터parameter로 사용할 수 있다.

     

    ✔️ 받아온 props 확인 (함수에서 파라미터로 사용)

    import React from "react";
    import { TouchableOpacity, Text } from "react-native";
    
    const MyButton = props => {
      console.log(props);
      return (
        <TouchableOpacity
          style={{
            backgroundColor: "#4B778D",
            padding: 16,
            margin: 10,
            borderRadius: 8,
          }}
          onPress={() => alert("Click!")}
        >
          <Text style={{ fontSize: 24, color: "white" }}>{props.title}</Text>
        </TouchableOpacity>
      );
    };
    
    export default MyButton;

    MyButton이라는 컴포넌트를 만들 때, props를 파라미터로 받아오고 있으며 받아온 파라미터를

    console.log(props);로 terminal에서 받아온 props값이 출력되게 하였고,

    <Text>컴포넌트 안에서

    {props.title}로 받아온 title props 값을 버튼 안에 직접 표시되도록 하고 있다.

    터미널에서 출력되는 받아온 props의 값

     

    ✔️ 컴포넌트의 태그 사이에 값을 입력하여 props를 전달

    import React from "react";
    import { Text, View } from "react-native";
    import MyButton from "./components/MyButton";
    
    const App = () => {
      return (
        <View
          style={{
            flex: 1,
            backgroundColor: "#fff",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Text style={{ fontSize: 30, marginBottom: 10, textAlign: "center" }}>
            My Button Component
          </Text>
          <MyButton title="props"></MyButton>
          <MyButton title="props">Another Props</MyButton>
        </View>
      );
    };
    
    export default App;

    <MyButton> 컴포넌트 태그 사이에 props를 지정해주었다.

    지정해준 값은 MyButton의 props의 children 속성으로 전달된다.

     

    첫번째 MyButton 컴포넌트는 props에 title만 전달되고

    두번째 MyButton 컴포넌트는 props에 title과 children이 모두 전달된다.

     

    import React from "react";
    import { TouchableOpacity, Text } from "react-native";
    
    const MyButton = props => {
      console.log(props);
      return (
        <TouchableOpacity
          style={{
            backgroundColor: "#4B778D",
            padding: 16,
            margin: 10,
            borderRadius: 8,
          }}
          onPress={() => alert("Click!")}
        >
          <Text style={{ fontSize: 24, color: "white" }}>
            {props.children || props.title}
          </Text>
        </TouchableOpacity>
      );
    };
    
    export default MyButton;

    props에 children이 있다면 title보다 우선시되도록 작성하였다.

    첫번째 MyButton에는 props에 children값이 없으므로 title이 표시되고

    두번째 MyButton에는 props에 children값과 title값이 모두 있기 때문에 children값이 표시된다.

    이렇게 props.children값이 태그 사이에 지정해준 "Another Props"로 전달되어 표시된다.

    ✔️ defaultProps

    import React from "react";
    import { Text, View } from "react-native";
    import MyButton from "./components/MyButton";
    
    const App = () => {
      return (
        <View
          style={{
            flex: 1,
            backgroundColor: "#fff",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Text style={{ fontSize: 30, marginBottom: 10, textAlign: "center" }}>
            My Button Component
          </Text>
          <MyButton title="props" />
          <MyButton title="props">Another Props</MyButton>
          <MyButton />
        </View>
      );
    };
    
    export default App;

    첫번째 MyButton에는 title만 props로 전달하고,

    두번째 MyButton에는 title과 children을 모두 props로 전달,

    세번째 MyButton에는 props로 아무것도 전달하지 않았다.

     

    이렇게 지정하였을 때, 화면에는

    이렇게 표시된다.

    세번째 MyButton은 props로 전달받은 값이 아무것도 없으므로 아무것도 표시되지 않는다.

     

    여러 사람과 함께 개발하는 경우 또는 실수를 방지하기 위한 방법으로 defaultProps를 지정해주면 위와 같이 아무것도 표시되지 않는 상황을 방지할 수 있다.

    import React from "react";
    import { TouchableOpacity, Text } from "react-native";
    
    const MyButton = props => {
      console.log(props);
      return (
        <TouchableOpacity
          style={{
            backgroundColor: "#4B778D",
            padding: 16,
            margin: 10,
            borderRadius: 8,
          }}
          onPress={() => alert("Click!")}
        >
          <Text style={{ fontSize: 24, color: "white" }}>
            {props.children || props.title}
          </Text>
        </TouchableOpacity>
      );
    };
    
    MyButton.defaultProps = {
      title: "default",
    };
    
    export default MyButton;

    defaltProps값으로 'default'라는 문자열을 지정해주었다.

     

    이렇게 defaltProps값을 사전에 지정해주면, props값으로 아무것도 넘겨주지 않더라도

    이렇게 아무것도 표시되지 않는 경우가 발생하지 않고, defaltProps 값으로 넘겨준 'default'라는 문자열이 나타난다!

     

    ✔️ propTypes

    프로젝트가 복잡해지면 컴포넌트에 props를 잘못 전달하는 경우가 발생할 수 있다. 이런 경우를 사전에 방지하기 위해 PropTypes를 사용하여 전달해야 하는 값의 type을 지정해주고, 잘못된 props가 전달되었을 때 경고 메시지를 통해 알릴 수 있다.

    PropTypes를 사용하려면 prop-types 라이브러리를 추가로 설치해야 한다.

    npm install prop-types

     

    PropTypes를 사용하면 컴포넌트에서 전달받아야하는 props의 타입과 필수 여부를 지정할 수 있다.

     

    import React from "react";
    import { TouchableOpacity, Text } from "react-native";
    import PropTypes from "prop-types";
    
    const MyButton = props => {
      console.log(props);
      return (
        <TouchableOpacity
          style={{
            backgroundColor: "#4B778D",
            padding: 16,
            margin: 10,
            borderRadius: 8,
          }}
          onPress={() => props.onPress()}
        >
          <Text style={{ fontSize: 24, color: "white" }}>
            {props.children || props.title}
          </Text>
        </TouchableOpacity>
      );
    };
    
    MyButton.defaultProps = {
      title: "defalut",
    };
    
    MyButton.propTypes = {
      title: PropTypes.string,
      onPress: PropTypes.func.isRequired,
    };
    
    export default MyButton;

    MyButton.js 파일안에서 MyButton의 propTypes를 위의 코드처럼 지정해주었다.

    title은 무조건 string으로 전달되어야하며,

    onPress는 function으로 전달되어야하고, 이 속성은 필수로 전달되어야한다. (필수 여부를 지정하는 방법은 선언된 타입 위에 '.isRequired'만 붙여주면 된다.)

     

    +) PropTypes에는 string, number, func, object, array등의 다양한 타입을 지정할 수 있다.

     

    onPress속성을 props값으로 받기 위해 MyButton 컴포넌트를 만드는 코드 안에서

    onPress={() => props.onPress()} 이렇게 수정하여 onPress속성값을 부모로부터 전달받을 수 있도록 하였다.

     

    App.js파일은

    import React from "react";
    import { Text, View } from "react-native";
    import MyButton from "./components/MyButton";
    
    const App = () => {
      return (
        <View
          style={{
            flex: 1,
            backgroundColor: "#fff",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Text style={{ fontSize: 30, marginBottom: 10, textAlign: "center" }}>
            My Button Component
          </Text>
          <MyButton title="props" onPress={() => alert("props!")} />
          <MyButton title="props" onPress={() => alert("children props!")}>
            Another Props
          </MyButton>
          <MyButton onPress={() => alert("default props!")} />
        </View>
      );
    };
    
    export default App;

    다음과 같이 수정하여, title은 string으로 지정하고, 모든 MyButton 컴포넌트안에 onPress 속성을 props로 지정하여 주었다. (title은 필수가 아니므로 마지막 MyButton은 지정해주지 않았고, defaultProp을 지정하였으므로 이것이 적용될 것이다.)

    왼쪽부터 차례로 props, Another Props, default 버튼을 눌렀을 때 나오는 화면이다.

     


     

     

    반응형

    댓글