[React-Native] Hook

rhkr9080·2022년 10월 8일
0

React-native

목록 보기
1/1

useState - Persist state within a component function

  • state : the current state
  • setState : a function to update our state

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.

  • reducer : a pure function that takses a state and and action, and returns a new state value based on the action
  • initialState : any inital state value, just like useState
  • initializer : a function called a lazily instantiate the initialState

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.

  • callback : a function with side effects
  • dependencies : an optional array containing dependency values

만약에 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

profile
공부방

0개의 댓글