interpolate - extrapolate
interpolate으로 동작의 변화를 주는데 내가 정한 수치보다 더 나아가서 계속 변화가 일어날때 그것을 방지하고자 사용한다. 수치보다 더 나아가고 싶다면 사용을 안해도 무방하다
extrapolate에는 3가지가 있는데
첫째로 "extend"는 끝이 한계치를 넘어서 계속 진행하는것이다.
둘째로 "identity"는
셋째로 "clamp"는 시작과 끝 점이 하나씩 있어서 다다르면 더이상 진행되지 않는다.
restSpeedThreshold 속도 임계점. 애니메이션을 끝난걸로 간주하는 속도
restDisplacemetnThreshold 거리 임계값 애니메이션이 끝난걸로 간주하는 거리
Realm SDK
백엔드가 없이 데이터베이스에 의존적인 어플을 만들수가 있다. 또한 MongoDB를 실행할 수 있게 해준다.
npm i realm
import Realm from 'realm'
realm을 import 하면 model을 정의해야한다.
const TaskSchema = {
name:"Task",
properties:{
_id: "int",
name: "string",
status: "string?",
},
primaryKey:"_id",
}
이를 가지고 데이터베이스와 연결해주어야 하는데 데이터베이스를 열기 위해서는 다음 코드를 사용한다.
const realm = await Realm.open(){
path: "myrealm",
schema: [TaskSchema]
});
다른 데이터를 추가하기 위해서는 schema에 추가하면 된다. 또한 이를 활성화 시키기 위해서 splash screen의 try & catch문을 통해서 시작해주면 된다.
다음으로 다른 컴포넌트와 함께 사용하기 위해 useContext hook을 사용할것이다.
// Context.js
//App에서 그냥 사용하게되면 경고창이 뜬다 보통 createContext는 따로 파일을 둔다.
export const DATAContext = React.createContext();
//App.js
export default function App() {
SplashScreen.preventAutoHideAsync();
const [appReady, setAppReady] = useState(false);
const [realm , setRealm] = useState(null)
useEffect(() => {
async function prepare() {
try {
const connection = await Realm.open){
path: "myrealm",
schema: [TaskSchema]
});
setRealm(connection)
await new Promise((resolve) => setTimeout(resolve, 2000));
} catch (e) {
console.warn(e);
} finally {
setAppReady(true);
}
}
prepare();
}, []);
const onLayoutRootView = useCallback(async () => {
if (appReady) {
await SplashScreen.hideAsync();
}
}, [appReady]);
if (!appReady) {
return null;
}
return (
<View style={{flex: 1}} onLayout={onLayoutRootView}>
<DATAContext.Provider value={realm}>
<NavigationContainer>
<Navigator />
</NavigationContainer>
</DATAContext.Provider>
</View>
);
}
createRealmContext
https://www.mongodb.com/docs/realm/sdk/react-native/quick-start/
2023년 12월 의 공식문서에 따르면 또 다른 방법이 있는데 React Native SDK 문서를 보면 createRealmContext를 사용하는 방법이다. useContext와 사용하는 방식이 비슷한데 설치를 해야하는 것이 하나 더 추가적으로 있다.
install
npm install realm
npm install @realm/react
type define
공식문서에서는 정적타입으로 지정해주었다.
// Define your object model
class Profile extends Realm.Object {
static schema = {
name: 'Profile',
properties: {
_id: 'objectId',
name: 'string',
},
primaryKey: '_id',
};
}
Realm에게 타입알려주기
import React from 'react';
import Realm, {ObjectSchema} from 'realm';
import {createRealmContext} from '@realm/react';
// Define your object model
class Profile extends Realm.Object<Profile> {
_id!: Realm.BSON.ObjectId;
name!: string;
static schema: ObjectSchema = {
name: 'Profile',
properties: {
_id: 'objectId',
name: 'string',
},
primaryKey: '_id',
};
}
// Create a configuration object
const realmConfig: Realm.Configuration = {
schema: [Profile],
};
// Create a realm context
const RealmContext = createRealmContext(realmConfig);
export default RealmContext
다음과 같이 설정해주면 schema type이 데이터베이스와 연동이 도었고 RealmContext를 전역으로 사용이 가능하다.
Write
create의 첫번째는 write하고자 하는 object의 name이다. 그리고 두번째는 그에 해당하는 것들의 값을 넣어주면 끝이다.
정말 쉽다.
//other.js
const Compname = ({navigation:{goBack})=>{
const realm = useContext(DATAContext);
const onClick = () +> {
realm.write(()=>{
realm.create("Task",{
_id: Date.now(),
name: " state Value ",
status: " state Value ",
})
})
//setStateOne(null)
//setStateOne("")
goBack() // 이를 이용한다면 state가 저절로 비어져 따로 setState할 필요가 없다.
}
return (
)
}
createRealmContext으로 Write를 사용하는 경우
const Write = ({navigation: {goBack}}) => {
const {useRealm} = realmContext;
const realm = useRealm();
const [selectEmo, setSelectEmo] = useState(null);
const [feeling, setFeeling] = useState("");
const onChangText = (text) => setFeeling(text);
const onEmoPress = (face) => setSelectEmo(face);
const onSubmit = () => {
if (feeling === "" || selectEmo === null) {
return Alert.alert("please..");
}
realm.write(() => {
realm.create("Feeling", {
_id: Date.now(),
emotion: selectEmo,
message: feeling,
});
});
goBack();
};
return (
<View>
Read
const Home = ({navigation: {navigate}}) => {
const realm = useContext(DATAContext)
const [feeling,setFeeling]=useState([])
useEffect(() => {
const feeling = useRealm.objects("Feeling");
// const anger = feeling.filtered("emotion = '🤬'"); // 필터링도 가능하다.
// 새로운 것을 추가했을 때 그것을 들어주는 함수 어떤 데이터 접근 같은 것을 넣기 위해 함.
setFeeling(feeling)
feeling.addListener(()=>{
console.log( 'detected something')
});
return () =>{
feelings.removeAllListeners()
}, []);
return (
<View>
<Title>Home</Title>
<Btn onPress={() => navigate("WRITE")}>
<Ionicons name="add" color="white" size={30} />
</Btn>
</View>
);
};
createRealmContext으로 Read하는 경우
const Home = ({navigation: {navigate}}) => {
const {useQuery} = realmContext;
const feeling = useQuery("Feeling");
useEffect(() => {
feeling.addListener(() => {
console.log("hohoh");
});
return () => {
feeling.removeAllListeners();
};
}, []);
//feeling으로 데이터를 출력할수있다.
Sorted(정렬)
const Home = ({navigation: {navigate}}) => {
const realm = useContext(DATAContext)
const [feeling,setFeeling]=useState([])
useEffect(() => {
const feeling = useRealm.objects("Feeling");
feeling.addListener((feeling,changes)=>{
// 첫번째 인자에는 작성한 data들이 담겨져있다.
/** 두번째 인자에는 array가 있는데
deletions insertions modifications newModifications oldModifications가 있다.
발생한 일에 대해 더 많은 컨트롤을 할 수 있다.
*/
setFeeling(feeling.sorted("_id",true)) // true라면 가장 큰 id에서 작은 순서로 정렬 false는 반대
});
return () =>{
feelings.removeAllListeners()
}, []);
return (
<View>
<Title>Home</Title>
<Btn onPress={() => navigate("WRITE")}>
<Ionicons name="add" color="white" size={30} />
</Btn>
</View>
);
};
Delete
지우는 방식은 두가지가 있는데 PrimaryKey를 이용한 삭제 방식과
item을 전체로 보내줘 삭제하는 방식이 있다.
const Home = ({navigation: {navigate}}) => {
const {useQuery, useRealm} = realmContext;
const realm = useRealm();
const feeling = useQuery("Feeling", (feeling) => {
return feeling.sorted("_id", true);
});
const onPress = (id) => {
realm.write(() => {
const feelRealm = realm.objectForPrimaryKey("Feeling", id);
realm.delete(feelRealm);
//realm.delete(id);
});
};
return (
<View>
<Title>Home</Title>
<FlatList
data={feeling}
ItemSeparatorComponent={Seperator}
keyExtractor={(feeling) => feeling._id + ""}
renderItem={({item}) => (
<TouchableOpacity onPress={() => onPress(item_id)}> //onPress(item)
<Record>
<Emotion>{item.emotion}</Emotion>
<Message>{item.message}</Message>
</Record>
</TouchableOpacity>
)}
/>
Layout Animations
https://reactnative.dev/docs/layoutanimation
Layout을 움직이게 해준다. 수의 변화가 생겨 렌더링이 될때 Animated를 만들지 않고 애니메이션을 진행시킬수 있다.
android 개발자라면 추가적으로 불러와야할 것들이 있는데. 다음과 같다.
import {
LayoutAnimation,
Platform,
UIManager,
View,
} from 'react-native';
if (
Platform.OS === 'android' &&
UIManager.setLayoutAnimationEnabledExperimental
) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
const Home = ({navigation: {navigate}}) => {
const {useQuery, useRealm} = realmContext;
const realm = useRealm();
const feeling = useQuery("Feeling", (feeling) => {
return feeling.sorted("_id", true);
});
useEffect(() => {
feeling.addListener((feeling, changes) => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
//LayoutAnimation.easeInEaseOut() 도 가능하다
});
return () => {
feeling.removeAllListeners();
};
}, []);
const onPress = (id) => {
realm.write(() => {
const feelRealm = realm.objectForPrimaryKey("Feeling", id);
realm.delete(feelRealm);
});
};