Skip to content

Instantly share code, notes, and snippets.

@r17x
Last active January 25, 2020 03:04
Show Gist options
  • Save r17x/f3a4619f1a575e42669b1e8f5e73cf79 to your computer and use it in GitHub Desktop.
Save r17x/f3a4619f1a575e42669b1e8f5e73cf79 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
/*
* @see { https://codesandbox.io/s/belajar-xstate-ezf3z }
*/
async function invokeFetchSubreddit(context) {
const { subreddit } = context;
const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`);
const json = await response.json();
console.log(json);
return json.data.children.map(child => child.data);
}
const createSubredditMachine = subreddit => {
return Machine({
id: "subreddit",
initial: "loading",
context: {
subreddit, // subreddit name passed in
posts: null,
lastUpdated: null
},
states: {
loading: {
invoke: {
id: "fetch-subreddit",
src: invokeFetchSubreddit,
onDone: {
target: "loaded",
actions: assign({
posts: (_, event) => event.data,
lastUpdated: () => Date.now()
})
},
onError: "failure"
}
},
loaded: {
on: {
REFRESH: "loading"
}
},
failure: {
on: {
RETRY: "loading"
}
}
}
});
};
// redditMachine
const redditMachine = Machine({
id: "reddit",
initial: "idle",
context: {
subreddits: {},
subreddit: ""
},
states: {
idle: {},
selected: {} // no invocations!
},
on: {
SELECT: {
target: ".selected",
actions: assign((context, event) => {
// Use the existing subreddit actor if one doesn't exist
let subreddit = context.subreddits[event.name];
if (subreddit) {
return {
...context,
subreddit
};
}
// Otherwise, spawn a new subreddit actor and
// save it in the subreddits object
subreddit = spawn(createSubredditMachine(event.name));
return {
subreddits: {
...context.subreddits,
[event.name]: subreddit
},
subreddit
};
})
}
}
});
createSubredditMachine("reactjs");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment