Realm React - v0.7.0

Realm React 로고

Realm React

더 나은 앱을 더 빨리 구축할 수 있습니다.

서론

React Native 애플리케이션에서 Realm을 설정하는 것은 역사적으로 복잡했습니다. 데이터베이스의 객체가 변경될 때 구성 요소를 다시 렌더링하려면 리스너를 수동으로 추가 및 제거해야 하는데, 이로 인해 상용구 코드가 많이 생성되고 오류가 발생하기 쉽습니다(마운트 해제 시 리스너가 제대로 제거된 경우). 이 라이브러리는 상태를 인식하는 Realm 데이터를 반환하는 React 후크 를 제공하여 이러한 문제를 완화합니다. 결과적으로 Realm 데이터가 변경되면 후크를 사용하는 컴포넌트가 다시 렌더링됩니다.

@realm/react 및 Realm에 대한 설명서는 docs.mongodb.org 에서 찾을 수 있습니다.

설치

이 라이브러리에는 react-native >= 0.59 및 realm >= 11이 필요합니다.

npm:

npm install realm @realm/react

원사:

yarn add realm @realm/react

사용해 보기

다음은 Realm React로 작성된 간단한 작업 관리자 애플리케이션입니다. React Native 애플리케이션에 복사하여 사용해 보세요!

import React, { useState } from "react";
import { SafeAreaView, View, Text, TextInput, FlatList, Pressable } from "react-native";
import { Realm, RealmProvider, useRealm, useQuery } from '@realm/react'

class Task extends Realm.Object {
_id!: Realm.BSON.ObjectId;
description!: string;
isComplete!: boolean;
createdAt!: Date;

static generate(description: string) {
return {
_id: new Realm.BSON.ObjectId(),
description,
createdAt: new Date(),
};
}

static schema = {
name: 'Task',
primaryKey: '_id',
properties: {
_id: 'objectId',
description: 'string',
isComplete: { type: 'bool', default: false },
createdAt: 'date'
},
};
}

export default function AppWrapper() {
return (
<RealmProvider schema={[Task]}><TaskApp /></RealmProvider>
)
}

function TaskApp() {
const realm = useRealm();
const tasks = useQuery(Task);
const [newDescription, setNewDescription] = useState("")

return (
<SafeAreaView>
<View style={{ flexDirection: 'row', justifyContent: 'center', margin: 10 }}>
<TextInput
value={newDescription}
placeholder="Enter new task description"
onChangeText={setNewDescription}
/>
<Pressable
onPress={() => {
realm.write(() => {
realm.create("Task", Task.generate(newDescription));
});
setNewDescription("")
}}><Text></Text></Pressable>
</View>
<FlatList data={tasks.sorted("createdAt")} keyExtractor={(item) => item._id.toHexString()} renderItem={({ item }) => {
return (
<View style={{ flexDirection: 'row', justifyContent: 'center', margin: 10 }}>
<Pressable
onPress={() =>
realm.write(() => {
item.isComplete = !item.isComplete
})
}><Text>{item.isComplete ? "✅" : "☑️"}</Text></Pressable>
<Text style={{ paddingHorizontal: 10 }} >{item.description}</Text>
<Pressable
onPress={() => {
realm.write(() => {
realm.delete(item)
})
}} ><Text>{"🗑️"}</Text></Pressable>
</View>
);
}} ></FlatList>
</SafeAreaView >
);
}

전체 예제를 보려면 템플릿 을 확인하세요.

Realm 후크

useRealm

createRealmContextRealmProvider 로 구성된 Realm 인스턴스를 반환합니다. 다음은 이 훅을 사용하여 구성 요소에 대한 쓰기 트랜잭션(write transaction) 콜백을 만드는 방법의 예입니다.

import {useRealm} from '@realm/react';
// assume props contain item a Realm.Object
const Component = ({item}) => {
const realm = useRealm();
const toggleComplete = useCallback((item) => {
realm.write(() => {
item.isComplete = !item.isComplete
})
},[item, realm])

return (
<Pressable
onPress={() =>
realm.write(() => {
item.isComplete = !item.isComplete
})
}><Text>{item.isComplete ? "✅" : "☑️"}</Text>
</Pressable>
)
}

useQuery

지정된 유형에서 Realm.Results 를 반환합니다. 이 후크는 collection의 객체가 변경될 때마다 업데이트되고 collection이 비어 있으면 빈 배열을 반환합니다. 그 결과는 모든 React Native VirtualizedList 또는 FlatListdata 인수에서 직접 사용할 수 있습니다. 목록의 renderItem 속성에 사용된 구성 요소가 React.Memo 로 래핑되면 수정된 객체만 다시 렌더링됩니다.

import {useQuery} from '@realm/react';

const Component = () => {
// ObjectClass is a class extending Realm.Object, which should have been provided in the Realm Config.
// It is also possible to use the model's name as a string ( ex. "Object" ) if you are not using class based models.
const sortedCollection = useQuery({
type: ObjectClass,
query: (collection) => {
// The methods `sorted` and `filtered` should be passed as a `query` function.
// Any variables that are dependencies of this should be placed in the dependency array.
return collection.sorted();
}
}, []);

return (
<FlatList data={sortedCollection} renderItem={({ item }) => <Object item={item}/>
)
}

useObject

지정된 유형 및 기본 키에 대해 Realm.Object 을 반환합니다. 후크는 반환된 객체의 속성이 변경될 때마다 업데이트하고, 객체가 존재하지 않거나 삭제된 경우 null 을 반환합니다.

import {useObject} from '@realm/react';

const Component = ({someId}) => {
// ObjectClass is a class extending Realm.Object, which should have been provided in the Realm Config.
// It is also possible to use the model's name as a string ( ex. "Object" ) if you are not using class based models.
const object = useObject(ObjectClass, someId);

return (
<View>
<Text>{object.name}</Text>
</View>
)
}

설정

RealmProvider

@realm/react 을 시작하려면 RealmProvider 로 앱을 래핑해야 합니다. RealmProvider 은(는) props를 사용하여 구성할 수 있습니다. 최소한 schema 프롭을 구성된 Realm 모델로 설정해야 합니다. RealmProvider의 모든 자식은 후크를 사용하여 Realm 데이터에 액세스하고 조작할 수 있습니다. 다음은 작업 모델로 Realm React를 설정하는 방법의 예입니다.

import { RealmProvider, useQuery, Realm } from '@realm/react';

const AppWrapper = () => {
return (
<RealmProvider schema={[Item]}>
<SomeComponent/>
<RealmProvider>
)
}

const SomeComponent = () => {
const items = useQuery(Item)
//..
}

또한 RealmProvider 에는 Realm이 열리기를 기다리는 동안 렌더링되는 대체 프롭과 함께 제공됩니다. 로컬 Realm의 경우 즉시 완료되지만 동기화된 Realm의 경우 더 큰 데이터 세트를 동기화하는 데 시간이 걸릴 수 있으며, 특히 앱을 처음 여는 경우 특히 그렇습니다. 이 경우 로딩 구성 요소를 폴백으로 제공하는 것이 좋습니다.

const AppWrapper = () => {
return (
<RealmProvider fallback={<Loading/>} >
<App/>
<RealmProvider>
)
}

인스턴스 클라이언트 재설정 폴백을 구현하는 등 일부 경우에는 RealmProvider 외부에서 구성된 Realm에 액세스해야 할 수 있습니다. useRef 를 사용하여 ref 을 생성하고 RealmProviderrealmRef 속성을 설정하여 이를 수행할 수 있습니다.

const AppWrapper = () => {
const realmRef = useRef<Realm|null>(null)

return (
<RealmProvider realmRef={realmRef}>
<App/>
<RealmProvider>
)
}

또한 앱에서 동일한 Realm의 여러 RealmProvider를 렌더링해야 할 수도 있습니다. 이 경우 기본적으로 closeOnUnmount 플래그를 false`` to prevent both Realm instances from closing when one has been removed from the component tree. This is set to true`로 설정할 수 있습니다.

const AppWrapper = () => {
return (
<RealmProvider closeOnUnmount={false}>
<App/>
<RealmProvider>
)
}

Realm 구성 동적으로 업데이트하기

RealmProvider 에 소품을 설정하여 영역 구성을 업데이트할 수 있습니다. RealmProvider 은(는) 가능한 모든 영역 구성 속성에 대한 속성을 사용합니다.

예를 들어 사용자 상태에 따라 동기화 구성을 설정할 수 있습니다.

const [user, setUser] = useState()

//... some logic to get user state

<RealmProvider sync={{ user, partition }}>

useApp 그리고 AppProvider

useApp 후크는 AppProvider 가 애플리케이션을 래핑하는 한 Realm 앱 인스턴스에 액세스하는 데 사용할 수 있습니다. 이 작업은 RealmProvider 외부에서 수행해야 합니다.

AppProvider 사용법:

import { AppProvider } from '@realm/react'
//...
// Wrap your RealmProvider with the AppProvider and provide an appId
<AppProvider id={appId}>
<RealmProvider sync={{user, flexible: true}}>
//...
</RealmProvider>
</AppProvider>

useApp 사용법:

// Access the app instance using the useApp hook
import { useApp } from '@realm/react'

const SomeComponent = () => {
const app = useApp();

//...
}

appRef 속성을 통해 AppProvider 외부의 앱에 대한 참고를 수신하는 것도 가능합니다. 이는 useRef 에서 반환된 React 참고로 설정되어야 합니다.

const AppWrapper = () => {
const appRef = useRef<Realm.App|null>(null)

return (
<AppProvider appRef={appRef}>
<App/>
<AppProvider>
)
}

useUser 그리고 UserProvider

UserProvider 이 도입되면 user 을 기본 Realm 구성에 자동으로 채울 수 있습니다. fallback 속성을 사용하여 로그인 구성 요소를 제공할 수 있습니다. 하위 구성 요소는 사용자가 인증되는 즉시 렌더링됩니다. 로그아웃하면 대체가 다시 표시됩니다.

UserProvider 사용법:

import { AppProvider, UserProvider } from '@realm/react'
//...
<AppProvider id={appId}>
<UserProvider fallback={LoginComponent}>
{/* After login, user will be automatically populated in realm configuration */}
<RealmProvider sync={{flexible: true}}>
//...
</RealmProvider>
</UserProvider>
</AppProvider>

useUser 사용법:

// Access the app instance using the useApp hook
import { useUser } from '@realm/react'

const SomeComponent = () => {
const user = useUser();

//...
}

인증 훅

다음 후크를 사용하여 애플리케이션에서 사용자를 인증할 수 있습니다. 이 필드는 인증 작업과 현재 결과의 진행 상황을 추적하기 위해 읽을 수 있는 단일 결과 객체를 반환합니다. 특정 인증 방법에 대한 자세한 내용은 사용자 인증 문서에서 확인할 수 있습니다.

result

result 을 반환하는 인증 후크는 다음과 같은 구조를 가집니다.

{
/**
* The current state of the operation.
* Enumerated by OperationState
*/
state, // "not-started", "pending", "success", "error"

/**
* The string name of the current operation running.
*/
operation,

/**
* Convenience accessors, so users can write e.g. `loginResult.pending`
* instead of `loginResult.state === OperationState.Pending`
*/
pending, // true or false
success, // true or false

/**
* The error returned from the operation, if any. This will only be populated
* if `state === OperationState.Error`, and will be cleared each time the
* operation is called.
*/
error // Error based object or undefined
}

useAuth

이러한 후크는 일반적으로 UserProviderfallback 구성요소에서 사용됩니다.

이를 사용하여 현재 로그인 작업의 상태를 managed 수 있습니다.

logIn

Realm.Credentials 인스턴스로 로그인합니다. 이를 통해 Realm에서 지원하는 모든 인증 메커니즘을 사용하여 로그인할 수 있습니다. 사용자가 현재 로그인되어 있을 때 이 함수가 호출되면 사용자가 전환됩니다.

const {logIn, result} = useAuth();

// Log in with a `Realm.Credentials` instance. This allows login with any authentication mechanism supported by Realm.
// If this is called when a user is currently logged in, it will switch the user.
// Typically the other methods from `useAuth` would be used.
// If this is rendered in the fallback of the `UserProvider`,
// then it's children will be rendered as soon as this succeeds.
useEffect( () => logIn(Realm.Credential.anonymous()), [] );
}

if(result.pending) {
return (<LoadingSpinner/>)
}

if(result.error) {
return (<ErrorComponent/>)
}

if(result.success) {
return (<SuccessComponent/>)
}
//...

logInWithAnonymous

익명 인증 제공자로 로그인합니다.

const {logInWithAnonymous, result} = useAuth();
const performLogin = () => {
logInWithAnonymous();
};

logInWithApiKey

API 키로 로그인합니다.

const {logInWithApiKey, result} = useAuth();
const performLogin = () => {
const key = getApiKey(); // user defined function
logInWithApiKey(key);
};

logInWithEmailPassword

이메일/비밀번호로 로그인합니다.

const {logInWithEmailPassword, result} = useAuth();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");

const performLogin = () => {
logInWithEmailPassword({email, password});
};

logInWithJWT

JSON Web Token(JWT)으로 로그인합니다.

const {logInWithJWT, result} = useAuth();

const performLogin = () => {
const token = authorizeWithCustomerProvider(); // user defined function
logInWithJWT(token);
};

logInWithGoogle

Google에 로그인합니다.

const {logInWithGoogle, result} = useAuth();

const performLogin = () => {
const token = getGoogleToken(); // user defined function
logInWithGoogle({idToken: token});
};

logInWithApple

Apple로 로그인합니다.

const {logInWithApple, result} = useAuth();

const performLogin = () => {
const token = getAppleToken(); // user defined function
logInWithApple(token);
};

logInWithFacebook

Facebook으로 로그인합니다.

const {logInWithFacebook, result} = useAuth();

const performLogin = () => {
const token = getFacebookToken(); // user defined function
logInWithFacebook(token);
};

logInWithCustomFunction

사용자 지정 함수로 로그인합니다.

const {logInWithFunction, result} = useAuth();

const performLogin = () => {
const customPayload = getAuthParams(); // user defined arguments
logInWithFunction(customPayload);
};

logOut

현재 사용자를 로그아웃합니다. 이렇게 하면 UserProviderfallback 가 즉시 렌더링됩니다.

const {logOut, result} = useAuth();

const performLogOut = () => {
logOut();
};

useEmailPasswordAuth

이 후크는 useAuth 와 유사하지만 특히 이메일/비밀번호 인증과 관련된 작업을 제공합니다. 여기에는 비밀번호 재설정 및 사용자 확인과 관련된 방법이 포함됩니다. useAuth 와 동일한 result 객체를 반환합니다.

logIn

이메일과 비밀번호로 사용자를 로그인하는 편의 함수 - 사용자는 `logIn(Realm.Credentials.emailPassword(email, 비밀번호)).

TypeDoc을 사용하여 생성됨