π‘ μ»΄ν¬λνΈλ?
μ¬μ¬μ©ν μ μλ 쑰립 λΈλ‘μΌλ‘, νλ©΄μ λνλλ UI μμμ΄λ€. κ·Έλ¬λ λ¨μν UI μν λ§ νλ κ²μ΄ μλ λΆλͺ¨λ‘λΆν° λ°μ μμ±μ΄λ μμ μ μνμ λ°λΌ ννμ΄ λ¬λΌμ§κ³ λ€μν κΈ°λ₯μ μνν©λλ€.
π‘ JSX
JSX λ λ§μΉ HTML μ μμ±ν κ² κ°μ μ½λμ΄λ€. μ΄λ¬ν JSX λ κ°μ²΄ μμ±κ³Ό ν¨μ νΈμΆμ μν λ¬Έλ²μ νΈμλ₯Ό μ 곡νκΈ° μν΄ λ§λ€μ΄μ§ νμ₯ κΈ°λ₯μΌλ‘ 리μ‘νΈ νλ‘μ νΈμμ μ¬μ©λλ€.
export default function App() {
return (
<View>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}
μ¬λ¬ κ°μ μμλ₯Ό ννν κ²½μ° νλμ λΆλͺ¨λ‘ κ°μΈμΌ νλ€. μμ κ²½μ° Text μ StatusBar νκ·Έλ₯Ό View νκ·Έλ‘ κ°μΈκ³ μλ€. View λ UI λ₯Ό ꡬμ±νλ κ°μ₯ κΈ°λ³Έμ μΈ μμλ‘ μΉ νλ‘κ·Έλλ°μμ <div> μ λΉμ·ν μν μ νλ μ»΄ν¬λνΈμ΄λ€. View μ»΄ν¬λνΈμ²λΌ μ¬λ¬ κ°μ μ»΄ν¬λνΈλ₯Ό λ°ννκ³ μΆμ κ²½μ° Fragment μ»΄ν¬λνΈλ₯Ό μ¬μ©νλ€. Fragment νκ·Έλ <Fragment> λ‘λ μ¬μ©νκ³ λ¨μΆ λ¬Έλ²μΌλ‘ <> λ‘λ μ¬μ©νλ€.
export default function App() {
return (
<>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
</>
);
}
π‘ if λ¬Έ
JSX λ΄μμ if λ¬Έμ μ¬μ©νλ €λ©΄ μ¦μ μ€ν ν¨μ ννλ‘ μμ±ν΄μΌ νλ€.
export default function App() {
const name = "hihi";
return (
<View style={styles.container}>
<Text style={styles.text}>
{(() => {
if (name === "Hanbit") return "My name is Hanbit";
else if (name === "Jeongmin") return "My name is Jeongmin";
else return "My name is React Native";
})()}
</Text>
<StatusBar style="auto" />
</View>
);
}
π‘ μΌν μ°μ°μ
if 쑰건문 λ³΄λ€ μΌν μ°μ°μλ₯Ό μ¬μ©ν μ μλλ‘ νκΈ°.
export default function App() {
const name = "Jeongmin";
return (
<View style={styles.container}>
<Text style={styles.text}>
My name is {name === "Jeongmin" ? "Jeongmin Park" : "React Native"}
</Text>
<StatusBar style="auto" />
</View>
);
}
μ± μ€ν νλ©΄
π‘ AND / OR μ°μ°μ
JSX μμ false λ λ λλ§λμ§ μκΈ° λλ¬Έμ AND μ°μ°μ μμ μ‘°κ±΄μ΄ μ°ΈμΌ λ λ€μ λ΄μ©μ΄ λνλκ³ κ±°μ§μΈ κ²½μ° λνλμ§ μλλ€. OR μ°μ°μλ AND μ°μ°μμ λ°λλ‘ μμ μ‘°κ±΄μ΄ κ±°μ§μΌ κ²½μ° λ΄μ©μ΄ λνλκ³ μ°ΈμΌ κ²½μ° λνλμ§ μλλ€.
// AND μ°μ°
export default function App() {
const name = "Jeong";
return (
<View style={styles.container}>
{name === "Jeongmin" && (
<Text style={styles.text}>My name is Jeongmin</Text>
)}
{name !== "Jeongmin" && (
<Text style={styles.text}>My name is not Jeongmin</Text>
)}
<StatusBar style="auto" />
</View>
);
}
// OR μ°μ°
export default function App() {
const name = "Jeongmin";
return (
<View style={styles.container}>
{name !== "Jeongmin" || (
<Text style={styles.text}>My name is Jeongmin</Text>
)}
{name === "Jeongmin" || (
<Text style={styles.text}>My name is not Jeongmin</Text>
)}
<StatusBar style="auto" />
</View>
);
}
JSX μμλ null μ νμ©νμ§λ§ undefined λ νμ©νμ§ μλλ€. (μ€λ₯ λ°μ)
π‘ μ€νμΌλ§
JSX μμλ HTML κ³Ό λ¬λ¦¬ style μ λ¬Έμμ΄λ‘ μ λ ₯νλ κ²μ΄ μλ κ°μ²΄ ννλ‘ μ λ ₯ν΄μΌ νλ€. κ·Έλ¦¬κ³ background-color μ²λΌ -(νμ΄ν) μΌλ‘ μ°κ²°λ μ΄λ¦μ μΉ΄λ© νκΈ°λ²μΌλ‘ backgroundColor μ²λΌ μμ±ν΄μΌ νλ€.
export default function App() {
const name = "Jeongmin";
return (
<View
style={{
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
}}
>
{name !== "Jeongmin" || (
<Text style={styles.text}>My name is Jeongmin</Text>
)}
{name === "Jeongmin" || (
<Text style={styles.text}>My name is not Jeongmin</Text>
)}
<StatusBar style="auto" />
</View>
);
}
π‘ Button μ»΄ν¬λνΈ
Button μ»΄ν¬λνΈμ onPress λ° title κ³Ό κ°μ μμ±μ μ¬μ©ν΄λ³΄μλ€.
import React from "react";
import { Text, Button, View } from "react-native";
const App = () => {
return (
<View
style={{
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
}}
>
<Text style={{ fontSize: 30, marginBottom: 10 }}> Button Component</Text>
<Button title="Button" onPress={() => alert("Click!!")} />
</View>
);
};
export default App;
μ± μ€ν νλ©΄
π‘ Custom μ»΄ν¬λνΈ
Button μ»΄ν¬λνΈλ IOS μ μλλ‘μ΄λμμ λ€λ₯Έ λͺ¨μ΅μΌλ‘ λ λλ§ λκΈ° λλ¬Έμ κ·Έ μ μ 보μνκΈ° μν΄μ TouchableOpacity μ»΄ν¬λνΈμ Text μ»΄ν¬λνΈλ₯Ό μ΄μ©ν΄μ MyButton 컀μ€ν μ»΄ν¬λνΈλ₯Ό λ§λ€μλ€.
// src/components/MyButton.js
import React from "react";
import { TouchableOpacity, Text } from "react-native";
const MyButton = () => {
return (
<TouchableOpacity
style={{
backgroundColor: "#3498db",
padding: 16,
margin: 10,
borderRadius: 8,
}}
onPress={() => alert("Click!!")}
>
<Text
style={{
fontSize: 24,
color: "white",
}}
>
My Button
</Text>
</TouchableOpacity>
);
};
export default MyButton;
// src/App.js
import React from "react";
import { Text, Button, 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 }}> My Button Component</Text>
<MyButton/>
</View>
);
};
export default App;
μ± μ€ν νλ©΄
π‘ props
props λ, λΆλͺ¨ μ»΄ν¬λνΈλ‘λΆν° μ λ¬λ μμ±κ° νΉμ μμλ°μ μμ±κ°μΌλ‘ λ³κ²½ν μ μλ€.
// src/components/MyButton.js
import React from "react";
import { TouchableOpacity, Text } from "react-native";
const MyButton = (props) => {
return (
<TouchableOpacity
style={{
backgroundColor: "#3498db",
padding: 16,
margin: 10,
borderRadius: 8,
}}
onPress={() => alert("Click!!")}
>
<Text
style={{
fontSize: 24,
color: "white",
}}
>
{/* children μ΄ μλ€λ©΄ title λ³΄λ€ λ μ°μ μλλλ‘ νλ κ² */}
{props.children || props.title}
</Text>
</TouchableOpacity>
);
};
MyButton.defaultProps = {
title: "Default",
};
export default MyButton;
props.children μ App.js μμ μ μΈν MyButton μ»΄ν¬λνΈ μ¬μ΄μ κ° "Children Props" μ΄λ€.
props.title μ App.js μμ μ μΈν MyButton μ»΄ν¬λνΈ μμ μ λ¬ν props μΈ title μ κ° "Button" μ΄λ€.
// src/App.js
import React from "react";
import { Text, Button, 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 }}>Props</Text>
<MyButton title="Button" />
<MyButton title="Button">Children Props</MyButton>
{/* title μ μ λ¬λ κ°μ΄ μμ κ²½μ° Default κ° title κ°μΌλ‘ λ€μ΄μ¨λ€. */}
<MyButton />
</View>
);
};
export default App;
μ± μ€ν νλ©΄
π‘ PropTypes
λΆλͺ¨ μ»΄ν¬λνΈμμ μ λ¬λ°μμΌ νλ props μ νμ κ³Ό νμ μ¬λΆλ₯Ό μ§μ ν μ μλ€.
npm install prop-types
// src/components/MyButton.js
import React from "react";
import { TouchableOpacity, Text } from "react-native";
import PropTypes from "prop-types";
const MyButton = (props) => {
return (
<TouchableOpacity
style={{
backgroundColor: "#3498db",
padding: 16,
margin: 10,
borderRadius: 8,
}}
{/* λΆλͺ¨ μ»΄ν¬λνΈμμ μ λ¬ν onPress ν¨μλ₯Ό μ΄λ²€νΈλ‘ λ°λλ€. */}
onPress={() => props.onPress()}
>
<Text
style={{
fontSize: 24,
color: "white",
}}
>
{/* children κ°μ΄ μλ€λ©΄ title μ΄ μμ΄λ children κ°μ 보μ΄λλ‘ νλ κ² */}
{props.children || props.title}
</Text>
</TouchableOpacity>
);
};
MyButton.propTypes = {
title: PropTypes.string.isRequired,
onPress: PropTypes.func.isRequired,
};
MyButton.defaultProps = {
title: "Default",
};
export default MyButton;
λΆλͺ¨ μ»΄ν¬λνΈ (App.js) μμ μ λ¬ν props μμ onPress λ₯Ό κΊΌλ΄μ λ²νΌ μ΄λ²€νΈλ‘ μ λ ₯νλ€.
// src/App.js
import React from "react";
import { Text, Button, 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 }}>Props</Text>
<MyButton title="Button" onPress={() => alert("props")} />
<MyButton title="Button" onPress={() => alert("children")}>
Children Props
</MyButton>
{/* title μ μ λ¬λ κ°μ΄ μμ κ²½μ° Default κ° title κ°μΌλ‘ λ€μ΄μ¨λ€. */}
<MyButton onPress={() => alert("default")} />
</View>
);
};
export default App;
π‘ state
state λ, μ»΄ν¬λνΈμμ μμ±λκ³ λ³κ²½μ΄ κ°λ₯ν κ°μ΄λ©° state λ₯Ό μ΄μ©ν΄μ μ»΄ν¬λνΈ μνλ₯Ό κ΄λ¦¬νλ€. Hook μ μ΄μ©ν΄μ ν¨μν μ»΄ν¬λνΈμμλ μν κ΄λ¦¬κ° κ°λ₯νλ€.
// src/components/Counter.js
import React, { useState } from "react";
import { View, Text } from "react-native";
import MyButton from "./MyButton";
const Counter = () => {
const [count, setCount] = useState(0);
return (
<>
<View style={{ alignItems: "center" }}>
<Text style={{ fontSize: 30, margin: 10 }}>{count}</Text>
<MyButton onPress={() => setCount(count + 1)}>μ¦κ°</MyButton>
<MyButton onPress={() => setCount(count - 1)}>κ°μ</MyButton>
</View>
</>
);
};
export default Counter;
count μ λν μνκ΄λ¦¬λ₯Ό μν΄ useState(0) λ₯Ό μ¬μ©νλ€.
μ¦κ°νλ λ²νΌμ ν΄λ¦νλ©΄ setCount κ° +1 μ΄ λκ³ κ°μνλ λ²νΌμ ν΄λ¦νλ©΄ setCount κ° -1 μ΄ λλ€.
// src/App.js
import React from "react";
import { Text, Button, View } from "react-native";
import MyButton from "./components/MyButton";
import Counter from "./components/Counter";
const App = () => {
return (
<View
style={{
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
}}
>
<Text style={{ fontSize: 30, marginBottom: 10 }}>Props</Text>
<Counter />
</View>
);
};
export default App;
μ± μ€ν νλ©΄
π‘ useState μ¬λ¬ κ° μ¬μ©νκΈ°
import React, { useState } from "react";
import { View, Text } from "react-native";
import MyButton from "./MyButton";
const Counter = () => {
const [count, setCount] = useState(0);
const [double, setDouble] = useState(0);
return (
<>
<View style={{ alignItems: "center" }}>
<Text style={{ fontSize: 30, margin: 10 }}>count : {count+double}</Text>
<MyButton onPress={() => setCount(count + 1)}>μ¦κ°</MyButton>
<MyButton onPress={() => setCount(count - 1)}>κ°μ</MyButton>
<MyButton onPress={() => setDouble(double + 2)}>2 μ¦κ°</MyButton>
<MyButton onPress={() => setDouble(double - 2)}>2 κ°μ</MyButton>
</View>
</>
);
};
export default Counter;
μ± μ€ν νλ©΄
π‘ Press Event
μ¬μ©μκ° νΉμ DOM μ ν΄λ¦νμ λ νΈμΆλλ onClick μ΄λ²€νΈμ λΉμ·ν μ΄λ²€νΈκ° press μ΄λ²€νΈμ΄λ€. TouchableOpacity μ»΄ν¬λνΈμμ μ€μ ν μ μλ Press μ΄λ²€νΈμ μ’ λ₯λ μ΄ 4 κ°μ§μ΄λ€.
1. onPressIn : ν°μΉκ° μμλ λ νΈμΆ
2. onPressOut : ν°μΉκ° ν΄μ λ λ νΈμΆ
3. onPress : ν°μΉκ° ν΄μ λ λ onPressOut μ΄ν νΈμΆ
4. onLongPress : ν°μΉκ° μΌμ μκ° μ΄μ μ§μλλ©΄ νΈμΆ
// src/components/EventButton.js
import React from "react";
import { TouchableOpacity, Text } from "react-native";
const EventButton = () => {
const _onPressIn = () => console.log("Press In !!!\n");
const _onPressOut = () => console.log("Press Out !!!\n");
const _onPress = () => console.log("Press !!!\n");
const _onLongPress = () => console.log("Long Press !!!\n");
return (
<TouchableOpacity
style={{
backgroundColor: "#f1c40f",
padding: 16,
margin: 10,
borderRadius: 8,
}}
onPressIn={_onPressIn}
onLongPress={_onLongPress}
onPressOut={_onPressOut}
onPress={_onPress}
delayLongPress={3000}
>
<Text style={{ color: "white", fontSize: 24 }}>Press</Text>
</TouchableOpacity>
);
};
export default EventButton;
λ²νΌμ ν΄λ¦νλ©΄
- μ§§κ² ν΄λ¦ν κ²½μ° : Press In -> Press Out -> Press
- κΈΈκ² ν΄λ¦ν κ²½μ° : Press In -> Long Press -> Press Out
delayLongPress={3000} μ 3μ΄ λμ λ²νΌμ λλ₯΄κ³ μμ΄μΌ onLongPress κ° νΈμΆλλ€λ μλ―Έμ΄λ€.
μ± μ€ν νλ©΄
π‘ onChange Event
// src/components/EventInput.js
import React, { useState } from "react";
import { View, Text, TextInput } from "react-native";
const EventInput = () => {
const [text, setText] = useState("");
const _onChange = (event) => setText(event.nativeEvent.text);
const _onChangeText = (text) => {
setText(text);
console.log("text: ", text);
};
return (
<>
<View>
<Text style={{ margin: 10, fontSize: 30 }}>text: {text}</Text>
<TextInput
style={{ borderWidth: 1, padding: 10, fontSize: 20 }}
placeholder="Enter a text...."
// onChange={_onChange}
onChangeText={_onChangeText}
/>
</View>
</>
);
};
export default EventInput;
onChange λ μ€μκ°μΌλ‘ λ³ννλ ν μ€νΈμ΄κ³ , μ€μ λ‘ νμν λ°μ΄ν°λ onChangeText μ΄λ€. μ¦, μ»΄ν¬λνΈμ ν μ€νΈκ° λ³κ²½λμμ λ λ³κ²½λ ν μ€νΈμ λ¬Έμμ΄λ§ μΈμλ‘ μ λ¬νλ©° νΈμΆνλ κ²μ΄λ€.
μ± μ€ν νλ©΄
λ³Έ ν¬μ€ν μ λμ [μ²μ λ°°μ°λ 리μ‘νΈ λ€μ΄ν°λΈ(νλΉλ―Έλμ΄, κΉλ²μ€ μ§μ)] λ₯Ό λ³΄κ³ κ³΅λΆνλ©° κΈ°λ‘νμμ΅λλ€.
'JavaScript > React-Native' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[React-Native] μ»΄ν¬λνΈ μ€νμΌλ§ (0) | 2021.11.04 |
---|---|
[React-Native] React Native μμνκΈ° (0) | 2021.11.02 |
λκΈ