The following example is a React Native counter that stores data to AsyncStorage. It uses store, events and effects.
import * as React from "react";import { Text, View, StyleSheet, TouchableOpacity } from "react-native";import AsyncStorage from "@react-native-community/async-storage";
import { createStore, createEvent, createEffect, sample } from "effector";import { useUnit } from "effector-react";
const init = createEvent();const increment = createEvent();const decrement = createEvent();const reset = createEvent();
const fetchCountFromAsyncStorageFx = createEffect(async () => { const value = parseInt(await AsyncStorage.getItem("count")); return !isNaN(value) ? value : 0;});
const updateCountInAsyncStorageFx = createEffect(async (count) => { try { await AsyncStorage.setItem("count", `${count}`, (err) => { if (err) console.error(err); }); } catch (err) { console.error(err); }});
const $counter = createStore(0);
sample({ clock: fetchCountFromAsyncStorageFx.doneData, target: init,});
$counter .on(init, (state, value) => value) .on(increment, (state) => state + 1) .on(decrement, (state) => state - 1) .reset(reset);
sample({ clock: $counter, target: updateCountInAsyncStorageFx,});
fetchCountFromAsyncStorageFx();
export default () => { const count = useUnit(counter);
return ( <View style={styles.container}> <Text style={styles.paragraph}>{count}</Text> <View style={styles.buttons}> <TouchableOpacity key="dec" onPress={decrement} style={styles.button}> <Text style={styles.label}>-</Text> </TouchableOpacity> <TouchableOpacity key="reset" onPress={reset} style={styles.button}> <Text style={styles.label}>0</Text> </TouchableOpacity> <TouchableOpacity key="inc" onPress={increment} style={styles.button}> <Text style={styles.label}>+</Text> </TouchableOpacity> </View> </View> );};
const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", paddingTop: 20, backgroundColor: "#ecf0f1", padding: 8, }, paragraph: { margin: 24, fontSize: 60, fontWeight: "bold", textAlign: "center", }, buttons: { flexDirection: "row", alignSelf: "center", justifyContent: "space-between", }, button: { marginHorizontal: 10, paddingVertical: 10, paddingHorizontal: 20, backgroundColor: "#4287f5", borderRadius: 5, }, label: { fontSize: 30, color: "#ffffff", fontWeight: "bold", },});