본문 바로가기
개발로그/ReactNative

다이어리 앱을 만들면서 연습해보자.- [R] Realm.filtered() 로 조회하고 Home.js 화면 그리기 / write.js에서 저장된 데이터를 Listenning해서 반영하기

by 그리너리디밸로퍼 2023. 2. 18.

이전글 

 처음부터 다시 해보는 npx create-react-native-app dear-diary with ios 세팅! 나만의 프리셋

 다이어리 앱을 만들면서 연습해보자. - 모듈설치 /Home / Write Screen

  다이어리 앱을 만들면서 연습해보자. - mongoDB 연동(Realm open/스키마 정의 하기)

 다이어리 앱을 만들면서 연습해보자. - context / [C] realm.write() / 창 닫기

저장된 데이터를 불러와서 필터링하기


const FeelingSchema = {
  name: "Feeling",
  properties: {
    _id: "int",
    emotion: "string",
    message: "string",
  },
  primaryKey: "_id",
};

///////////////////
    
    //스키마에서 name으로 데이터를 가져온다.
    const feelings = realm.objects("Feeling");
    
    // filtered( "query string") 조회할 수 있다.
    
    const happy = feelings.filtered("emotion = '🤗'");

조회 결과 

[{"_id": 1676609525951, "emotion": "🤗", "message": "Asssa!"},
{"_id": 1676609542333, "emotion": "🤗", "message": "Asssa!"},
{"_id": 1676609654451, "emotion": "🤗", "message": "Asssa!"}]

realm에서 조회한 데이터를 FlatList로 랜더링 했다.

Home.js 컴포넌트 

    <Content>
      <Title>My feelings</Title>
      <FlatList
        data={feelings}
        renderItem={({ item }) => (
          <Record>
            <Emotion>{item.emotion}</Emotion>
            <Message>{item.message}</Message>
          </Record>
        )}
        keyExtractor={(feeling) => feeling._id + ""}
        ItemSeparatorComponent={Seperator}
        contentContainerStyle={{ paddingVertical: 10 }}
      ></FlatList>
      <WriteBtn onPress={onPress}>
        <WriteTxt>
          <Ionicons name="add" size={32} color="white" />
        </WriteTxt>
      </WriteBtn>
    </Content>

 

Write.js에서 저장한 feelings 데이터로 Home.js화면 업데이트하기

const Home = ({ navigation }) => {
  const realm = useDB();
  const [feelings, setFeelings] = useState([]);
  
  useEffect(() => {
    // Home 컴포넌트가 mount 될때 조회해서 state에 등록한다.
    const feelings = realm.objects("Feeling");
    setFeelings(feelings);
    // feelings 가 수정/삭제/생성 등의 이벤트가 있을 때 감지하기 위한 리스너를 등록한다.
    feelings.addListener(() => {
      // 변화가 감지되면 다시한번 데이터를 가져와 state에 등록한다.
      const feelings = realm.objects("Feeling");
      console.log("edting feeling!");
      setFeelings(feelings);
      // write화면에서 데이터를 추가하면 즉시 home에서 다시 그려진다.
    });
    // Home 컴포넌트가 unmount 될 때 모든 리스너를 삭제한다.
    return () => {
      feelings.removeAllListeners();
    };
  }, []);
  
  ...
  }

이런 플로우라고 이해하고  공식문서에서 realm에 addListener()를 했을때, 에 관한 내용을 보면 .

리스너는 두개의 param을 받는데, 첫번째는 현재 tasks, 두번째는 변경사항에 대한 정보이다. 

// Define the collection notification listener
function listener(tasks, changes) {
  // Update UI in response to deleted objects
  changes.deletions.forEach((index) => {
    // Deleted objects cannot be accessed directly,
    // but we can update a UI list, etc. knowing the index.
    console.log(`A task was deleted at the ${index} index`);
  });
  // Update UI in response to inserted objects
  changes.insertions.forEach((index) => {
    let insertedTasks = tasks[index];
    console.log(
      `insertedTasks: ${JSON.stringify(insertedTasks, null, 2)}`
    );
    // ...
  });
  // Update UI in response to modified objects
  // `newModifications` contains object indexes from after they were modified
  changes.newModifications.forEach((index) => {
    let modifiedTask = tasks[index];
    console.log(`modifiedTask: ${JSON.stringify(modifiedTask, null, 2)}`);
    // ...
  });
}
// Observe collection notifications.
tasks.addListener(listener);

그러니 위에 처럼 , 이벤트가 감지되었다고 해서 다시 조회하고 state에 등록하는 같은 행동을 두번 할 필요가 없는 것. 

// Listener 에서 받은 파라미터를 로그로 찍어보면 아래와 같다. 

//tasks
[{  [{"_id": 1676609525951, "emotion": "🤗", "message": "Asssa!"},
{"_id": 1676609542333, "emotion": "🤗", "message": "Asssa!"},
{"_id": 1676609654451, "emotion": "🤗", "message": "Asssa!"},
{"_id": 1676609916845, "emotion": "😊", "message": "Happy"},
{"_id": 1676609944921, "emotion": "🤬", "message": "Angry"}, 
{"_id": 1676610111303, "emotion": "🤬", "message": "Angry"} ]}]

//changes (insert 발생시)
{"deletions": [], "insertions": [6], "modifications": [], "newModifications": [], "oldModifications": []}

그러니 파라미터를 받아서 그대로 state에 업데이트만 해주면 됨. 

    feelings.addListener((feelings, changes) => {
      // 변화가 감지되면 다시한번 데이터를 가져와 state에 등록한다.
      // _id를 기준으로 역순정렬함.(10,9,8..)
      setFeelings(feelings.sorted("_id", true));
      // write화면에서 데이터를 추가하면 즉시 home에서 다시 그려진다.
    });

다음글 

2023.02.19 - [개발로그/ReactNative] - 다이어리 앱을 만들면서 연습해보자. - [D] realm.delete() / [U]

728x90

댓글