Skip to content

Instantly share code, notes, and snippets.

@keith-kurak
Last active January 12, 2022 03:55
Show Gist options
  • Select an option

  • Save keith-kurak/4962633d3abb44eff12519e3da8bf4f1 to your computer and use it in GitHub Desktop.

Select an option

Save keith-kurak/4962633d3abb44eff12519e3da8bf4f1 to your computer and use it in GitHub Desktop.
02: Hello, MobX State Tree!
Edit each file in order in this gist to complete the section!
// create store with mock channels to read
// create a type used by your RootStore
const Channel = types.model("Channel", {
id: types.number,
name: types.string,
});
// fill in the fields in the RootStore
const RootStore = types
.model("RootStore", {
channels: types.optional(types.array(Channel), []),
})
.views((self) => ({
get channelsSorted() {
// like to do this since it automatically does .slice() so arrays aren't weird once they get to React
return sortBy(self.channels, (c) => c.id);
},
}));
// Also fill in the mockChannels with data!
// Wrap App in StoreProvider so useStore will work inside the screens
// wrap the existing JSX in the StoreProvider
export default function App() {
return (
<StoreProvider>
{/* ... */}
</StoreProvider>
);
}
// switch channels screen from inline mock channels to mock channels from MST
// wrap the component in an observer
export default observer(function ChannelsScreen({ navigation }) {
const rootStore = useStore(); // get the store from the hook
// ...
// change the data source of the FlatList
data={rootStore.channelsSorted}
// ...
// adding functionality to add channels
// Chain .actions to the end of the RootStore definition
.actions((self) => {
const addChannel = () => {
self.channels.push({
id: self.channels.length,
name: uniqueNamesGenerator({
dictionaries: [adjectives, animals],
length: 2,
separator: "-",
}) /* names like: "awesome-ocelot" */,
});
};
return {
addChannel,
};
});
// add the button to add a channel
// get access to the RootStore
const rootStore = useStore();
// add left button to add channels
options={({ navigation }) => ({
headerLeft: () => (
<Pressable
style={
({ pressed }) => [
{ opacity: pressed ? 0.5 : 1.0 },
] /* touchable with opaciity */
}
onPress={() => rootStore.addChannel()}
>
<Feather name="plus" size={18} style={Platform.OS === 'web' && { paddingHorizontal: 10 }} />
</Pressable>
),
})
// add login/ logout functionality
// add isLoggedIn variable to model
isLoggedIn: types.optional(types.boolean, true), // set to true for now since we don't really have login sessions yet
// add actions to toggle isLoggedIn
const login = () => {
self.isLoggedIn = true;
}
const logout = () => {
self.isLoggedIn = false;
}
return {
addChannel,
login,
logout,
};
// add logout button that uses RootStore functionality
// make a logout button
const rootStore = useStore();
// ...
<Button onPress={() => rootStore.logout()} title="Logout" />
// do the same thing as logout, but in reverse!
// ...
<Button onPress={() => rootStore.login()} title="Login" />
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment