qcoding

[ReactNative_study_14] useContext , Realm SDK DB 본문

ReactNative

[ReactNative_study_14] useContext , Realm SDK DB

Qcoding 2021. 12. 20. 15:39
반응형

 

*이 내용은 Nomad coder의 React Native Master Class를 듣고 공부하는 글입니다.

 

1) Realm SDK DB 사용

https://docs.mongodb.com/realm/sdk/react-native/install/

 

Install Realm for React Native — MongoDB Realm

Docs Home → MongoDB RealmThe MongoDB Realm React Native SDK enables development of React Native applications using the JavaScript and TypeScript languages. React Native enables you to build cross-platform iOS and Android apps with a single codebase using

docs.mongodb.com

1-1) Schema 생성

-> DB 내에서 구성할 자료의 구조를 정의한다. 옆에 ? 가 있는 것은 필수가 아닌 옵션이다.

    나중에는 primaryKey를 가지고 저장된 자료값을 확인한다.

// 구조
const TaskSchema = {
  name: "Task",
  properties: {
    _id: "int",
    name: "string",
    status: "string?",
  },
  primaryKey: "_id",
};

//사용예시
const contentSchema = {
  name: "contet",
  properties: {
    _id: "int",
    emotion: "string",
    message: "string",
  },
  primaryKey: "_id",
};

1-2) Open

-> 보통 app이 실행될 때 db에 있는 자료를 가져온다. 해당 프로젝트에서는 App.js에서 App loading을 사용하여 구현하였다. 2021.11.22 - [ReactNative] - [React Native study_1] Expo API

 // data를 불러올 때 ready  
  const [ready, setReady] = useState(false);

//Apploading이 끝날 때 실행되는 함수
  const onFinish = () => setReady(true);

//Apploading이 시작될 때 실행되는 함수
  const startLoading =  async () => {
    const realm = await Realm.open({
      path: "myrealm",
      schema: [contentSchema],
    });
    console.log(realm)
  }

  
  if (!ready) {
    return (
      <AppLoading
        onError={(e)=>console.log(e)}
        startAsync={startLoading}
        onFinish={onFinish}
      />
    );
  }

1-2) Write 데이터 저장

realm.write(() => {
  task1 = realm.create("Task", {
    _id: 1,
    name: "go grocery shopping",
    status: "Open",
  });
  
  
// 프로젝트에서 예시
// 여기서 "content" 부분은 schema에 써있는 name 이다.
realm.write(()=>{
            const realmData=realm.create("content", {
                _id: Date.now(),
                emotion : selectedEmotion,
                message : contentText,
              });
            console.log(realmData)
        })

1-3) DB 내용 가져오기

    // useContext를 통해 value에 있는 값을 가져온다.
    const relam=useContext(DBContext);
    
    
    useEffect(()=>{
        // "content"는 schema name이며 해당하는 object를 가져온다.
        const content=relam.objects("content");
    },[])

1-4) DB 내용 가져와서 FILLTER 사용

//emotion 중 😎를 가지고 있는 object만 불러오기

  const content=relam.objects("content");
  const sunglasses=content.filtered("emotion = '😎'");
  console.log(sunglasses);


// console.log값
  Array [
    Object {
      "_id": 1639980475002,
      "emotion": "😎",
      "message": "ggggg",
    },
  ]

*** UseEffect / eventListener를 활용한 data 다시 불러오기

-> data가 업데이트 됐을 때, 다시 불러오기 위해서 사용함.

    useEffect(()=>{
    
    	// id값이 시간이므로 true로 해서 시간이 큰것부터 아래로 내려가게 정렬해서 저장한다.
        const content=relam.objects("content");
        setContent(content.sorted("_id",true))
        
        // 위에서 만든 content 변수에 이벤트가 생길 때 실행되는 함수
        // 이 때 위에서 한 것 처럼 db내에서 데이터를 다시 가져온다.
        content.addListener(()=>{
            const content=relam.objects("content");
            setContent(content.sorted("_id",true))
        })
        
        // 앞에서 만든 Listener를 없애준다.
        return () => {
            content.removeAllListeners();
          };
    },[])

1-5) DB내에서 삭제하기

https://docs.mongodb.com/realm/sdk/react-native/examples/read-and-write-data/

 

Read & Write Data - React Native SDK — MongoDB Realm

Docs Home → MongoDB RealmThe examples on this page use the following schemas:const TaskSchema = { name: "Task", properties: { _id: "int", name: "string", priority: "int?", progressMinutes: "int?", }, primaryKey: "_id",};const PersonSchema = { name: "Pers

docs.mongodb.com

-> Primary Key를 이용하여 DB내에서 특정 data를 찾을 수 있다.

  // 받아온 item내에 있는 _id를 통해서 "content" 안에 있는 특정 값을 찾는다.
  const delteItem=(item)=>{
        relam.write(() => {
            const selectedItem = relam.objectForPrimaryKey("content", item._id);
            
            // 삭제하는 함수
            relam.delete(selectedItem);
            // console.log(selectedItem)
          });
    }
    
    
    
<Wrapper 
    showsVerticalScrollIndicator={false}
    data={content}
    keyExtractor={(item)=>item._id+""}
    ItemSeparatorComponent={() => <View style={{ height: 10 }} />}
    renderItem={({item})=>
    	{
        return(
          <CardBox onPress={()=>{delteItem(item)}}>
              <CardEmotion>{item.emotion}</CardEmotion>
              <CardText>{item.message}</CardText>
          </CardBox>
    		)
   	}
    }
 >

 

 

2) useContext Hook 사용

-> 보통 React에서는 props 형태로 parent -> child로 데이터를 전달한다. useContxt는 데이터를 components간에 전달하기 위해 쓰이며, 맨위에 있는 App.js에서 Container로 감싸주면 아래에 있는 component에서 접근이 가능하다.

2-1) 불러온 DB 데이터를 저장하기

const [realm,setRealm]=useState(null);


  const startLoading =  async () => {
    const realm = await Realm.open({
      path: "myrealm",
      schema: [contentSchema],
    });
    setRealm(realm)
  }

2-2) Context 만들기

// 다른 받는 쪽에서 useContext를 쓸 때 아래의 변수를 가져다 쓰므로 export 필요함.

export const DBContext=createContext();

2-3) Context Provder로 전체 Componet 감싸고 value로 값 보내기

  return (
    <DBContext.Provider value={realm}>
      <NavigationContainer>
        <StatusBar style="auto" />
        <StackNav></StackNav>
      </NavigationContainer>
    </DBContext.Provider>
  );

2-4) 다른 하위 component엣 useContext를 통해 data 전달받기

import {DBContext} from '../App'
// import 해준 DBContext를 가져옴
const realm= useContext(DBContext);

** 이렇게 하면 아래와 같이 에러가 발생하는데 이는 App.js에서 만든 DBContext를 다시 가져오면서 생기는 문제이다.

이를 위해서 DBContext 를 생성하는 것을 별도의 js파일을 만든다.

Require cycle: App.js -> navigation\StackNav.js -> screens\Write.js -> App.js

Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle.

// 문제 해결을 위해 context.js 파일을 만들고 아래내용을 써준다.

export const DBContext=createContext();

 

반응형
Comments