useState - Persist state within a component function
E.g.
const [state, setState] = useState(initialValue)
E.g.
import React, { useState } from 'react'
import { View, Text, Button } from 'react-native'
const randomDiceRoll = () => Math.floor(Math.random() * 6) + 1
export default function App() {
// diceRoll을 useState의 param로 초기화
// 지금은 "배열"로 초기화 되었음!
const [diceRolls, setDiceRolls] = useState([])
return (
<View>
<Button
title="Roll dice!"
onPress={() => {
// diceRoll을 setDiceRoll로 update
// 현재 diceRoll === [...diceRoll]
// setDiceRolls([...diceRolls, randomDiceRoll()])
setDiceRolls([...diceRolls, randomDiceRoll()])
// 연속적으로 setDiceRoll을 호출해도 첫 호출만 실행됨
// React가 16ms단위로 Batch Update를 하기 때문
// setDiceRolls([...diceRolls, randomDiceRoll()])
// setDiceRolls([...diceRolls, randomDiceRoll()])
// 일정시간 동안 변화한 상태를 한번에 렌더링하는 비동기적 동작
// setDiceRolls((prevState) => [...prevState, randomDiceRoll()])
}}
/>
{diceRolls.map((diceRoll, index) => (
<Text style={{ fontSize: 24 }} key={index}>
{diceRoll}
</Text>
))}
</View>
)
}
useReducer - Similar to useState, but for state that involves multiple sub-values. We typically use useReducer when our state has multiple sub-values, e.g. an object containing keys that we want to update independently.
E.g.
import React, { useReducer } from 'react'
import { View, Text, TextInput } from 'react-native'
// reducer 함수 동작 부문
function reducer(state, action) {
switch (action.type) {
case 'first':
return { ...state, first: action.value }
case 'last':
return { ...state, last: action.value }
}
}
export default function App() {
// useReducer(함수(reducer), state 초기값)
const [state, dispatch] = useReducer(reducer, { first: '', last: '' })
return (
<View>
<TextInput
style={{ fontSize: 32 }}
placeholder="First"
// value와 state.first 연결
value={state.first}
// dispatch(first를 onChange Event 발생시 변경)
onChangeText={(text) => {
dispatch({ type: 'first', value: text })
}}
/>
<TextInput
style={{ fontSize: 32 }}
placeholder="Last"
// value와 last를 연결
value={state.last}
// dispatch(last를 onChange Event 발생 시 변경)
onChangeText={(text) => {
dispatch({ type: 'last', value: text })
}}
/>
<Text style={{ fontSize: 32 }}>
Hello {state.first} {state.last}
</Text>
</View>
)
}
useEffect - Perform side effects when component is mounted(at first), and unmounted, and updated.
만약에 deps 배열(dependencies)을 비우게 된다면, 컴포넌트가 처음 나타날때에만 useEffect 에 등록한 함수가 호출됩니다.
그리고, useEffect 에서는 함수를 반환 할 수 있는데 이를 cleanup 함수라고 부릅니다. cleanup 함수는 useEffect 에 대한 뒷정리를 해준다고 이해하시면 되는데요, deps 가 비어있는 경우에는 컴포넌트가 사라질 때 cleanup 함수가 호출됩니다.
(출처 : https://react.vlpt.us/basic/16-useEffect.html)
E.g.
import React, { useState, useEffect } from 'react'
import { Button } from 'react-native'
export default function App() {
const [count, setCount] = useState(0)
const countEvery3 = Math.floor(count / 3)
//
useEffect(() => {
console.log(countEvery3)
}, [countEvery3])
// onPress Event가 발생하면
// setCount(count+1)
// this.count = count+1
return (
<Button
title={`Increment ${count}`}
onPress={() => {
setCount(count + 1)
}}
/>
)
}
useRef - Create and update a single mutable value that exists for the lifetime of the component instance
const refContainer = useRef(initialValue);
State의 변화 -> Render -> Component 내부 변수들 초기화
Ref의 변화 -> Render X -> Component 내부 변수들 그대로 유지
==> State 대신 Ref에 값을 저장해 불필요한 Rendering 방지
import { useState, useRef } from 'react'
import { Text, View, Button } from 'react-native'
export default function App() {
const [render, setRender] = useState(false);
const countRef = useRef(0);
let countVar = 0;
console.log('***** 렌더링 후 Ref:', countRef.current);
console.log('***** 렌더링 후 Var:', countVar);
// Why is countVar maintaing its value as 0?
// render()가 될때마다 countVar는 다시 0으로 초기화
const increaseVar = () => {
countVar = countVar + 1;
console.log('Var Up! --->', countVar);
}
// Ref의 생애주기는 App이 mount~unmount이므로 계속 유지됨
// 따라서, render()가 되어도 component의 전 생애주기 동안 유지.
// 앱을 다시 실행해도 유지되는듯...?
const increaseRef = () => {
countRef.current = countRef.current + 1;
console.log('Ref Up! --->', countRef.current);
}
const doRender = () => {
setRender(!render);
}
return (
// React-native에서는 html의 최상단의 <> </>이 필수
// <div>는 <View>로 대체
<View>
<Text>Ref: {countRef.current}</Text>
<Text>Var: {countVar}</Text>
{/* Button은 button이 아니라 Button임...*/}
{/* prop에 title을 "무조건" 넣어야함 */}
<View>
<Button title="Ref Up!" onPress={increaseRef}>Ref Up!</Button>
<Button title="Var Up!" onPress={increaseVar}>Var Up!</Button>
<Button title="Render!" onPress={doRender}>Render!</Button>
</View>
</View>
);
}
출처
https://react.vlpt.us/basic/
https://www.reactnative.express/react/hook/
https://ko.reactjs.org/docs/hooks-reference.html
https://itprogramming119.tistory.com/entry/React-useRef-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EC%98%88%EC%A0%9C