React Native self QnA

·2020년 9월 8일
0

좌충우돌

목록 보기
17/26

1. Authentication

https://reactnavigation.org/docs/auth-flow 여기 마지막에서 2번째의 코드(snack.expo.io) 에 대해 궁금한 점 정리

(1) Hooks: useContext, createContext, useMemo

https://en.reactjs.org/docs/hooks-reference.html#additional-hooks

useContext, createContext

const value = useContext(MyContext);

context object(React.createContext에서 returned된 value)를 받고,
return current context value(determined by the value prop of the nearest <MyContext.Provider> above the calling comp in the tree) for that context.

가장 가까운 <MyContext.Provider> above the comp가 업데이트하는 경우,
this hook will trigger a rerender with the latest context value passed to that MyContext Provider.
조상이 React.memo 나 shouldComponentUpdate를 쓰는 경우에도, a rerender will still happen starting at the component itself using useContext.

// 예시 코드
const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

context에 대한 자세한 설명(필요 이유 등)은 여기 참고.

useEffect

useEffect(didUpdate);

By default, effects 는 매번 render가 끝날 때마다 run한다. But 특정 값이 바뀌었을 때만 render를 할 수도 있다. 주로 side effects를 담당한다.

Cleaning up an effect

memory leaks를 예방하기 위해 하는 것으로,
component가 UI에서 removed되기 전에 previous effect is cleaned up before executing the next effect라는 기능을 실행한다.

Conditionally firing an effect

useEffect()의 두번째 인자로 effect가 depend하는 값을 array 형태로 집어넣으면 해당 값이 바뀔 때마다 useEffect()가 run할 수 있다(매번 component가 render할 때마다=default가 아니라)

// 예제 코드
useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

"create" function과 array of dependencies를 인자로 삼고 return memoized value.
인자로 받은 function은 rendering 도중에 run한다.

만약 인자로 받는 array of dependencies가 비어있는 경우, new value가 rerender될 때마다 computed될 것. 반대로 array of dependencies가 채워져 있는 경우, 해당 array의 값들이 변할 때만 rerender한다.

You may rely on useMemo as a performance optimization, not as a semantic guarantee.

useContext, useReduce에서 performance optimization을 위해 쓰인다.

(2) Hooks: useState, useReducer

useState

const [state, setState] = useState(initialState);

Returns a stateful value, and a function to update it.
state: 처음에 initialState으로 초기화됨.

setState(newState)

를 통해 newState로 state 값이 바뀌고, 바뀌는 걸 적용하기 위해 rerender함.

Bailing out of a state update

newState == state일 경우, render는 다시 하되, 트리 속으로 파고들어 모든 걸 다 바꾸지 않음(newState != state일 때보다 시간적 비용이 훨씬 덜하다는 걸 뜻하는 듯)

useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init);

useReducer는 redux에서 제공하는 state, dispatch를 거의 유사하게 제공한다고 한다.
useReducer을 개념적으로 이해하기 위해 redux의 개념을 잠깐 짚고 넘어가자.

React는 React 컴포넌트 자신이 개별적으로 상태관리를 하나,
react+redux는 상태관리를 하는 전용 창고(store: 커다란 json 결정체 정도의 이미지)이 있다. 이 경우 react 컴포넌트는 그걸 보여주는 용도로만 쓰임.

따라서, useReducer에서

  • state는 store에 존재하는 아주 신성한 무언가. 따라서 react component가 바로 접근할 수 없음.
  • store의 문지기=reducer가 action의 발생(store에 대해 뭔가를 하는 것)을 감지하면 store에 있는 state가 갱신됨.
  • dispatch: 준비 단계(react component)=>실행 단계(reducer)로 넘겨주는 역할을 하는 함수라고 생각하기.

++
useState와 비슷한데 더 complex state logix과 multiple sub-values를 가졌을 때 또는 다음 state이 previous state에 depend하는 경우에 자주 쓴다고 함.

매번 callback을 component에 넘기는 것보다 dispatch 하나 pass하는 게 더 낫다고 한다.

// 예제 코드
const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

즉,

Counter: 준비 => dispatch(): 준비-실행 주관 => reducer(): 실행
준비-실행 단계를 주관하는 dispatch에서 던져준 type: decrement를 문지기 reducer가 받아서 action 요청이 들어왔네? 하고 switch문으로 분기별로 action을 처리 해준다.

출처1: https://medium.com/@ca3rot/아마-이게-제일-이해하기-쉬울걸요-react-redux-플로우의-이해-1585e911a0a6
출처2: react 공식튜토리얼

(3) async storage

https://react-native-community.github.io/async-storage/docs/api

여기 참고하기.

profile
이것저것 개발하는 것 좋아하지만 서버 개발이 제일 좋더라구요..

0개의 댓글