본문 바로가기
코딩생활/ReactNative

[React Native] 3-6 LogContext로 배열 상태 관리하기

by InfoJun 2023. 3. 15.
반응형

이제 WriteScreen 우측 상단의 체크 버튼을 누르면 현재 작성한 제목과 내용을

 

LogContext 안의 배열에 추가하는 기능을 구현해보겠습니다.

 

기존에 LogContext에서 만든 text 상태는 지우고

 

logs라는 배열을 useState로 상태 관리 하겠습니다.

 

그 다음에 LogContext.Provider의 value에 이 logs 배열을 객체로 감싸서 넣겠습니다.

 

객체로 감싸는 이유는 추후 logs 배열 외에도 상테에 변화룰 주는 다른 함수가 들어가기 때문입니다.

 

comtexts/LogContext.js

import {createContext, useState} from 'react';
import React from 'react';

const LogContext = createContext();

export function LogContextProvider({children}) {
  const [logs, setLogs] = useState([]);
  return (
    <LogContext.Provider value={{logs}}>
      {children}
    </LogContext.Provider>
  );
}

export default LogContext;

 

이제 제목과 내용을 받아와서 배열에 추가하는 onCreate라는 함수를 만들텐데,

 

배열에 항목을 추가할 대는 고유한 값이 있어야 합니다.

 

이번에는 고유한 값을 생성해주는 uuid라는 라이브러리를 사용하겠습니다.

 

$ yarn add uuid

 

UUID는 범용 고유 식별자로서, 표준으로 사용되는 고유 식별자 형식입니다.

 

UUID는 5가지 버전이 있는데 , 일반적으로 랜덤하고 고유한 식별자를 생설할 때는 v4를 많이 사용합니다.

 

import {v4} from 'uuid';
v4();

 

사용은 위와 같이 하면 됩니다.

 

이 라이브러리는 Node.js의 crypto 기능을 사용하는데, 리액트 네이티브는 기본적으로 내장되어 있지 않습니다.

 

따라서 react-native-get-random-values라는 라이브러리를 설치하여 호환하여야합니다.

 

$ yarn add react-native-get-random-values
$ npx pod install

 

그 후 프로젝트 최상위 디렉토리에 있는 index.js 파일을 열어서 맨위에 다음 코드를 작성해주세요.

import 'react-native-get-random-values'

그리고 앱을 재시작해주세요.

 

contexts/LogContext.js

import {createContext, useState} from 'react';
import React from 'react';
import { v4 } from 'uuid'

const LogContext = createContext();

export function LogContextProvider({children}) {
  const [logs, setLogs] = useState([]);
  
  const onCreate = ({title, body, date}) => {
    const log = {
      id: v4(),
      title,
      body,
      date
    }
    setLogs([log, ...logs])
  }
  
  
  return <LogContext.Provider value={{logs,onCreate}}>{children}</LogContext.Provider>;
}

export default LogContext;

Log 작성 기능 마무리하기

WriteScreen에서 useContext를 사용해 LogContext값을 받아오고

 

onSave라는 함수를 만들겠습니다.

 

onSave 함수를 완성하고 WriteHeader에 Props로 넣어주어 체크 버튼을 누를 때 이 함수를 호출합니다.

 

screens/WriteScreen.js

import React, { useContext, useState } from "react";
import {View, StyleSheet, KeyboardAvoidingView, Platform} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';
import WriteHeader from '../components/WriteHeader';
import WriteEditor from '../components/WriteEditor';
//작성한 부분 
import {useNavigation} from "@react-navigation/native";
import LogContext from "../contexts/LogContext";
// ----

function WriteScreen() {
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');
  //작성한 부분----
  const navigation = useNavigation()
  
  const {onCreate} = useContext(LogContext);
  const onSave = () => {
    onCreate({
      title,
      body,
      date : new Date().toISOString(),
    })
    navigation.goBack();
  }
  //-----
  return (
    <SafeAreaView style={styles.block}>
      <KeyboardAvoidingView
        style={styles.avoidingView}
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}>
        //달라진부분
        <WriteHeader onSave = {onSave} />
        //-----
        <WriteEditor
          title={title}
          body={body}
          onChangeTitle={setTitle}
          onChangeBody={setBody}
        />
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
}

(...)

 

components/WriteHeader.js  --체크버튼

function WriteHeader({onSave}) {
  //onSave 추가
  const navigation = useNavigation();
  const onGoBack = () => {
    navigation.goBack();
  };
  return (
    <View style={styles.block}>
      <View style={styles.iconButtonWrapper}>
        <TransparentCircleButton
          onPress={onGoBack}
          name="arrow-back"
          color={'#424242'}
        />
      </View>
      <View style={styles.buttons}>
        <TransparentCircleButton
          name="delete-forever"
          color={'#ef5350'}
          hasMarginRight
        />
        <TransparentCircleButton
          name={'check'}
          color={'#009688'}
          onPress={onSave}
        />
        //onPress 부분 추가
      </View>
    </View>
  );
}

(...)

 

WritedHeader에서 체크버튼을 보여주고 있는 TransparentCircleButton에

 

onPress props로 onSave Props를 전달하였습니다.

 

이제 배열이 내용에 잘 추가되는지 확인하기 위해

 

FeedScreen에서 useContext를 사용해 Logcontext의 값을 받아온 뒤 ,logs 배열을 콘솔에 출력해 보겠습니다.

 

screens/FeedsScreen.js

import React, {useContext} from 'react';
import {View, StyleSheet, TextInput} from 'react-native';
import LogContext from '../contexts/LogContext';
import FloatingWriteButton from '../components/FloatingWriteButton';

function FeedsScreen() {
  const {logs} = useContext(LogContext);
  console.log(JSON.stringify(logs, null, 2));

  return (
    <View style={styles.block}>
      <FloatingWriteButton />
    </View>
  );
}

const styles = StyleSheet.create({
  block: {
    flex: 1,
  },
});

export default FeedsScreen;

 

JSON.stringfy()를 사용할 때 두 번째와 세 번째 파라미터를 이와 같이 설정해주면

 

객체나 배열을 출력할 때 공백과 새 줄을 포함해 보기 좋게 출력해 줍니다.

잘 출력이 된다면 log 코드는 지워줍니다.

반응형

댓글