 We're in Hot Jam's parentheses, TAC. And hopefully that's the right place. But we're going to be talking about building a music discovery app with Drupal 8 and React. And kind of looking at some of the things that I learned along the way being new to those two things. So anybody who came in late, that link there, Billy Link will take you to the repository. Code resources, slides are all there if you're into that sort of thing. So I am Brian Perry. I am an interactive developer at HS2 Solutions. I live in the Chicago suburbs. Kind of a popular opinion these days, but I am a lover of all things component and component-driven. So building with components in Drupal 8, things like pattern libraries and pattern lab, and then increasingly component-based approaches within JavaScript frameworks like React. And then I'm also a lover of all things Nintendo. So if you want to track me down and tell me the cool stuff you're playing on your Nintendo Switch, I'm down. I'm into that. And I'm also on the internet in a bunch of different places. So I'd love to internet with you. So I work at HS2 Solutions. We have a couple of offices in the Chicago area. Thanks to them for sending me here and letting me do this. I'm not great at the company info slide, but what I like to say is that we have a great Drupal practice at HS2. It's among a handful of things that we do. But I get to work with a bunch of great Drupalers and learn a lot from them. So if you are looking to do some great Drupal work, we're often hiring. And if you are looking to have great Drupal work done, I'm sure we'd like to talk to you. So let's talk a little bit about kind of how this came together. So this is a lyric from LCD Soundsystem's album, American Dream, one of my favorites from last year. I'm a fan. Luck is always better than skill at things. And I find sometimes when it comes to learning new things or working on side projects, the ones that I find that I learned the most from are where things kind of fall together sometimes somewhat unexpectedly. And I think this project was a little bit of that. So let's take a look at how this all came together. This is a picture of me. I used to perform comedy. This is me performing my solo musical show, Brianme Sound Machine. And so it's relevant for a couple of reasons. One is that all comedians secretly want to be musicians. And I was no exception. Another one is that a comedian that I collaborated with a bunch in Boston, his name was Chris Duffy. And Chris went to college with one of the folks behind this podcast called Switched On Pop. And Switched On Pop, great podcast. I'd encourage you listening to it. But they take a look at modern pop music and break things down from more of like a music theory or musicology perspective, sometimes even like from a classical approach to understand why today's pop music does or doesn't work. And I was listening to an episode a while back at this point where their guest was Rob Mitchum. Rob's also from the Chicago area. And what he was on to talk about is every year he maintains a Google spreadsheet where he takes all of the best of lists, best of album lists and aggregates them together into one massive best of, best of list. And I thought to myself when I heard that, that that's an interesting data set that I'd like to work with at some point if I could find a way to do that. This is a screenshot of what that spreadsheet looks like. To some people this might be a thing of beauty, to others it may be incredibly panic inducing. I'm more in the panic inducing camp but there's a lot of great data here. All the albums, the genres that the albums fall into where they rank on all the lists, way off to the side there's averages and like a calculated consensus score. So tons of really awesome data here in a Google spreadsheet. And then also kind of around the same time I'm starting to hear, so this I believe is a picture of Dries and Baltimore being attacked by a bird which was unfortunate. But I'm starting to hear a lot about decoupled Drupal. And so decoupled and things like progressively decoupling, fully decoupling. We don't really say headless anymore but we say decoupled and I heard a lot about decoupled. There are a few projects that I'd worked on where we had some pieces that kind of fall into this category but I wanna learn more about why it's gaining so much momentum in the Drupal community, the different approaches to it. And then also around the same time I'm hearing a lot in big gigantic bold letters about React and the React ecosystem and things like React with Redux. And I'm sure there are other wonderful JavaScript frameworks but I'm just hearing so much chatter and talk about React, I wanna understand why people are so excited about it and wanna learn more about it. So it eventually kind of clicked with me that I have these pieces that might work well together. I've got this data set that I'd love to work with, I wanna learn more about decoupled Drupal in Drupal 8 and I wanna learn more about React. So a great excuse to try to jam all these things together and learn some cool stuff. And speaking of that and speaking of jam, I also kind of realized that this seems to be the jam stack that I'm hearing about. So what the jam stack is, jam stands for JavaScript, it's JavaScript on the client side so it's not server rendered or isomorphic JavaScript. APIs, yes the A in jam stands for APIs, little inception there and then markup and often that's static pre-rendered markup. I'm realizing that I'm kind of building in that stack and I'm hearing things about why the jam stack can be beneficial. So some of those reasons are improved performance, better scaling, improved developer experience, higher security and with a list like that I would also assume free pony rides. But skepticism aside, I definitely since I am gonna be developing the stack anyway, I wanna understand more about how these benefits happen, how I can take advantage of them and just learn more in general. And also the security part sounds pretty good, especially recently if you were participating in our community driven denial of service attack. So anyway, so now it's kind of at the point where I've got this thing I wanna try to take on and I need to figure out how I'm gonna approach it. So I can figure out how exactly I'm gonna approach decoupling in this case. And some of these lyrics are a bit of a stretch, this is probably one of them, but it's definitely the the plot and phase of the project. And also I wanted to include this just because I really respect Jay Huss's continued dedication to the bucket hat as a fashion choice. So let's look at the different flavors for decoupling. A lot of this comes from Dries's How Did A Couple, How Did A Couple in 2018 post. If you haven't read that, I encourage it, but at a high level, there is coupled. So traditional Drupal that you all know and love. And in this case, Drupal handles the rendering of the page and you're building with all of the Drupal things that you love and the contrib ecosystem and building a website as you've traditionally known. And then there's progressively decoupling. So this is Drupal kind of with some strategically sprinkled in JavaScript framework magic, potentially. Think of something like a block that maybe is something like React and that is calling to an API that Drupal provides to get additional data as it needs it. And so, but still in this case, Drupal is handling the initial rendering of the page. And then there's fully decoupled. And in fully decoupled, the JavaScript framework of choice handles the initial rendering of the page and then it's gonna communicate with Drupal's API to get content as it needs it. So this is a little flowchart. It's probably a little washed out and hard to read. Portion of the flowchart from the How Did A Couple in 2018 post. Really, what I'm trying to get across with including this is just the idea that it's not necessarily a black and white choice. There's a lot of things you have to consider when you're trying to figure out where on this scale of coupled to fully decoupled you're gonna land. But as you kind of shift away from coupled into something more fully decoupled, you're losing out on some of the things that you may have come to know and love with Drupal. So be it, you know, the editing experience, previewing content, accessibility and markup. But you're potentially gaining some improvements in developer experience. Maybe you have a team of JavaScript developers who are already comfortable with one of these frameworks. So whether or not things are driven by editorial needs, might put you more on the coupled side, developer experience on the fully decoupled side, or somewhere in the middle being progressively decoupled. But in my case, it actually was kind of a black and white decision. I didn't really have any editorial needs or they're at least very limited. The data in the spreadsheet was kind of a secret sauce here for me. It's nice that I can edit in Drupal, but really I just want that data in API. And then for me, I wanted to learn more about React. So the idea of actually stripping away my Drupal security blanket and being forced to go all in on React was a positive for me. So now we know the kind of general approach to the coupling we wanna take. So now we can think about how we're gonna stand up our Drupal-based API. So over the past year or so, it's crazy to think that it's really only been a year, but there's been a lot of movement in the community related to the decoupled or API-first distributions. So this lyric is from SZA's album. I'm either mispronouncing her name or there's just no way that I can possibly say SZA and sound cool, but either way. But maybe I should pray a little harder or work a little smarter. And especially as I tried out some of these distributions, if they fit your needs, it's an opportunity to potentially work a little smarter. So at the time that I kind of took this project on, this is what the available options were. There was Reservoir, which is one of Acquia's API-first distributions. And since then, there's also Headless Lightning as an option, which if you're familiar with lightning. And my understanding is that the focus is potentially shifting more to Headless Lightning. Then there's Contenta, which is another API-first distribution from the community, which has a lot of momentum now. And then also you can still take the pieces that make up these distributions and create something similar in Drupal 8. So let's look at some of the things that these API distributions have in common. So they have API-focused admin UIs. So the top menu is Contentas, and you see things like content models and API there. And then below that is Reservoir. So there's also API and content models, but you can tell looking at the two of them, that Reservoir is as much more stripped down. And as I understand, that was kind of an intentional choice with the project where they were trying to find kind of the most streamlined path into standing up a Drupal-based API, even potentially for people who were not as familiar with Drupal. And then they also offer some automatic API documentation through Schimata and OpenAPI, I believe. But here's an example of what you see. All of the endpoints that are available, listed on the left-hand side, explanations of how you can filter and sort and affect your request, and then an example response. And having that all automatically documented and available to you is really awesome. And then also, let's not forget, it provides an API that you can hit. Both Reservoir and Contenta use JSON API by default. So you get a nice response in the JSON API standard. Here we see data for Kendrick Lamar's album, Damn, which we'll see a lot of, because it is without a doubt the number one critical consensus for the best album of last year. Check it out. So, again, I kind of touched on it going through those similarities, but so Reservoir is definitely more of the minimalist approach to one of these API-first distributions. Contenta keeps some of the things that you might come to expect with Drupal as far as flexibility and the ability to configure things. It also can work with things like taxonomies and media out of the box, which Reservoir doesn't really do. And then you can definitely, I'm sure there's some secret sauce in those distributions, but a lot of the things are contributed modules that you can take advantage of. So if you have especially custom requirements or you need to layer this onto an existing project, you can certainly roll your own. But I would ask you, especially if you're kind of starting from the beginning or on a level playing field, do you have the option to pray a little harder and work a little smarter? In my case, I went with Contenta. I had really simple needs, so something super minimal was great. It worked with like no configuration for me. So I basically like composer installed and had an API that I could hit. I think I was a little early on Contenta at the time. It wasn't quite that for me. I have since used Contenta for other projects and like it quite a bit. And as I mentioned, it has momentum in the community. So that's probably what I'd personally look at first. But for this project I used Reservoir and it worked really nicely. So now we know how we're gonna stand up Drupal and the next thing we gotta think about is how are we gonna get that data into Drupal so we can send it through our API? So to paraphrase Kenny Loggins, a pretty good get for Thundercat here. What if I told you, babe, it's all so easy? Definitely a bit of an exaggeration, but what we'll see in a second, kind of what Drupal can offer through the Migrate API and Migration is pretty amazing as I'm sure some of you guys in the room know and it really helped make this a lot easier for me. And then speaking of Thundercat and the song Show You the Way, there is a wonderful spoken word interlude on it. So for anyone who is out and about in Nashville at DrupalCon, fast reader over there and socializing, take Thundercat's advice and hydrate. It's really important. If there's one thing you take away from this talk, it's hydrate, put that in your session feedback. So how in God's name are we gonna get the data from this Google spreadsheet into Drupal? And in my case, I specifically don't wanna like get a copy of the spreadsheet in my code base. I don't wanna have to create a copy Google spreadsheet or anything of that like that. I wanna be able to hit the spreadsheet where it stands and get the most recent version of the data because someone else is maintaining it. And also because at least during that December period when the lists get published, this data does change pretty frequently. So as I alluded to Drupal Migrate to the rescue here, I created a custom Migrate module that we'll look at a little more closely. And then it also installs an album content type. I clicked through the UI and built it and then exported it from Drupal console to be able to include it in my module. And then I use the JSON migration in the Migrate Plus module to get data from the Google spreadsheets. And then I'm also augmenting the data as it comes in with some data from the Spotify API to add some nice little bells and whistles cause everybody loves bells and whistles. There's a weird little hack that makes some of this possible. So in a Google spreadsheet, if you go file and then publish to web, you or in my case, if you nicely email the guy who maintains this and asks him to do it for you, you can say to publish the entire document as a web page. And if you say automatically republish when any changes are made, you get a URL that you could hit as long as you know your document ID where you can get a JSON response with all of your data from your Google spreadsheet. And it's always up to date. It does have a little weird kind of structure or naming conventions, but once you take a look, it's definitely something you can wrap your head around. So now I have that data ready to go and I can start building my migration. So this is a YAML file that defines my migration and it lives in AOTY Migrate config install. So I give it an ID and a label and I'm using a custom source plugin. We'll look at that next, but most of what that does is interact with the Spotify API. And then I'm fetching HTTP and parsing JSON. I've got my ugly Google spreadsheet URL as far as where it's looking for its data. The item selector is basically where in this response it's gonna get all of the items that it's gonna migrate. So in this case, it's feed slash entry. And then I define all the fields from my source here. So I give them a name and a label and then a selector from that feed slash entry point. Again, the naming's a little funky. There's that dollar sign T where the string actually lives. But once you get the first one, it's pretty easy to define those and map those. And then we're using the node destination plugin and we're saying that we're going to land this in the album content type that I created. And then we do our source mappings here. So we're just saying for the source fields that we've defined, specifying where in our album content type it's gonna land. And then now let's look at the source plugin. So this is album source plugin PHP. It lives in AOTY migrate plugin migrate source. And it's using the Spotify web API for PHP, which I found worked pretty nicely for my needs. And we're extending the URL source plugin and implementing prepare row, prepare rows where we're doing our work here. So at first we're basically just creating a session with the Spotify API, getting a token back. And then once we have our token, we can search against the Spotify API. And the spreadsheet has an album column. And what the album column actually has in it, it just so happens, is the album name and also the artist name, which gives us a pretty nice unique string that we can search against Spotify to get the right album. And once we do that, we're just pulling some data out of what we get back from the API that we're just gonna add to Drupal. So we're setting some additional source fields. The first one is the Spotify album ID. And when we have that, we can do some cool stuff on the client side, like link over to Spotify to play the album. We could embed it, I didn't quite get that far, but, and then also there's URLs to the cover art in a couple of different sizes and formats. So we grab those as well. And then we return the modified row. So at this point, we can run our migration and more like migrate, am I right? Is that my mom over there reacting to that joke? I don't know. But we see all of the data in Drupal, listed out on the content page here. And if we edit one of the nodes, Kendrick Lamar again, because of course, we see exactly what we think we'd see, all the stuff from the spreadsheet, Spotify album ID, the averages and calculated scores and where it ranks on all the lists. So now we have all this great data in Drupal, an API that can serve it out. And we are ready to rock and roll. Let me check where we're at, time wise, doing pretty good. Okay, so now we've got our API ready to serve that data and we can get to the React part of things. So you know how are we gonna build our React app? How are we gonna take advantage of that data from our API in our application? And there's a lot to talk about React-wise here, definitely more than I can talk about in the time that I have. But what I'm gonna focus on are just kind of the high-level learnings that I had as somebody who was somewhat new to React and also definitely new to using React alongside this Drupal API that I built. So paraphrasing Jay-Z here, as I always do. You know, I've been to Paris at least two times and coming from Jay-Z, that is extremely humble that he's only been to Paris twice. At least, at least, yeah, who knows? Maybe Jay-Z's just really trying to be humble. But so, spoiler alert, we'll start by looking at the app, just where it ended up currently. So I'll try to click it and actually load a webpage here on the Wi-Fi, we'll see how that goes. Yay! Okay, so yeah, let's take a quick tour through the app because I think it'll make a little bit more sense in context when we break things down. So we saw the spinner in the beginning, we were getting data from our Drupal API, and we, by default, are on this cover view, so we see a list of all the albums, and if we click on one of them, like we click on Lord, the detail panel on the right-hand side updates, and we see the cover art, we see a link here where we can play the album on Spotify. So here we see Lord's album. And, whoops. There's also all of the lists that it is part of and where it ranks, and we can click any of these, I'll click Pitchfork, repping Chicago here, but you can see the list and what they had to say about Lord and where it ranks and all that good stuff. And then also, if we go on the left-hand side here, there's a little control panel, so we can do some filtering and sorting and otherwise changing things. We do something simple, like limit the number of results that are available there, but we can also filter by artist or album or genre. So if I, the War on Drugs was my favorite album of last year, so if I type in War, we'll see that as I type, the data filters and updates there, and now I see all of the albums that contain War in the title or artists that have War. I can also, as I am, want to do search for hip-hop, and now I see the same sort of representation of the data, but just specifically focused on all of the hip-hop albums of 2017. And then there's other visualizations I can swap between with the tabs up here, so this just gives me a table view. This is from the Blueprint.js library, which provides a number of nice little building block react components you can use. They had a nice table. And when I first kind of took an initial shot at this project, I definitely bit off way more than I could chew being kind of new to React. I was like, all right, I'm gonna get my data from my API and try to build a line chart or a bar chart and didn't get too far. And then when I kind of scaled back and just took this table component and said, all right, I'm gonna try to take the data that I have in my API and represented it in a table in my React app just so I can see something that looks pretty similar to the spreadsheet and then start to layer on filtering and sorting from there. It was a lot easier for me. So that definitely helped out a lot. But the same visualization you can do things like resort it. So if I instead sort by the artist, it's just the table updates and I see everything sorted by the artist name. And then there's also this list view, which is another visualization based on the same data. It's kind of a heat map. So we see across the top all of the different lists and then the 50 albums that we are showing here where they rank on all those lists and kind of how commonly they show up on all the other lists. It gets interesting when you do something like sort by a particular list. So if I look at just rolling stone here, I see everything sorted by one through 50 for rolling stone. And I can look at like the first album here, Kendrick Lamar and see that it shows up high on pretty much every list. But then if I look at something like three songs of experience by U2, it's not on any other best of list of the year. So way to be you rolling stone. And Bono's not here, is he? Is he, he didn't make it? All right, I'm cool. I had some nastier things to say about Bono the last time we gave this talk. But that's the basic of what the app can do now. So let's look a little bit about how, I always do that, how we built it. So the first question you're gonna ask yourself is how do I make a React app? How do I bootstrap a React app? And there's a package create React app maintained by the Facebook team I believe that lets you quickly bootstrap a React app, perfect naming for it. And it also hides a lot of the configuration behind the scenes. So also when I first started trying to learn React, create React app didn't exist yet. So you had to create a webpack configuration or find a webpack boilerplate and adjust it to your needs. So it's nice to be able to have this to kind of get you up and running quickly and get more into the working with React, understanding if React is for you kind of stuff. So I installed it as a global package here and that lets me run create React app and provide the name of my project. And as anyone who's used NPM before is familiar with, it's gonna give you a bunch of output that I definitely didn't wanna copy and paste into this fake terminal window. And if you change into your project directory, you're gonna see all the files that it bootstrapped for you, but you can also run NPM start. And that's gonna start a little development server so you can see your app in your browser, but it's also gonna do hot module reloading so that if you change something in your app, the changes will be reflected automatically in the browser, which is nice. And then you can also run NPM run build and that's gonna build a production ready bundle of your app. So an asset that you can deploy somewhere pretty much anywhere since it's a static bundle. And then beware there are dragons ahead. So I mentioned that it keeps that create React app keeps a lot of the configuration behind the scenes. There's also the concept of ejecting from create React app so you can run NPM run eject. And what that does is exposes all of the configuration so you get access to your webpack file for dev and production and all kinds of other stuff, which is great that it's there if you need it. I would say that don't be embarrassed if you're rolling with the default create React app config as long as it works for you, but know that whenever you need to you have that escape hatch. For this project I actually haven't had to eject from it yet but ironically for this slide deck I had to eject create React app to get it to do everything I needed it to do. So a handful of other places we can go from here but to kind of follow through the flow of our data from our API. Let's look at getting the data into our React app. So there's a handful of ways that you can do this. You could use a library called Axios which is similar to jQuery's Ajax methods but I wanted to experiment with the JavaScript fetch API a little bit. So I created a utility function here called get all album data. It takes an endpoint and defines a array of albums. And this is probably a good point to mention that some of the JavaScript we're gonna be looking at is gonna use ES6 JavaScript syntax. So if you're not familiar with ES6 that's why things might look a little different. I'm hoping that it's as we talk through it it'll be enough that you can kind of generally understand the concept but if you're scratching your head that might be why. So we call fetch with our endpoint and fetch returns a promise and we're gonna chain a few promises together to act on the data that we get back. So after our first promise the first thing that we're doing is we're resolving the response and getting the JSON data out of it. And then we're acting on the data. So we're taking our albums and we're adding them to the album array and then if there is a next page of results from the API we're gonna call get all album data recursively with the next page of results and if not we'll just return our albums cause we've got them all. When I first started working with JSON API I was a little bit surprised that there was no way to just get all of the data in one shot but it kind of makes sense because you usually don't wanna do that. In my particular case for this app for just the data for 2017 getting everything upfront performs fine but I know that in future years like if I have multiple years or 2018 I'll probably have to adjust this so I can get it in smaller chunks. And then also there's just a little bit of logging if something goes wrong. Certainly more than I could do there. Okay, so now we actually have a React app. We have our data from our API in it and we can start looking about how we can make use of it in our app and how we can build some components here. So this is a look at our album component. It's Kendrick Lamar cause it's always gonna be Kendrick Lamar. And in our little source code preview panel on the right hand side we see our render method. So what's being rendered out there is JSX and JSX is a templating language commonly used by React that lets you write HTML element like markup that is then translated to JavaScript. And so what we see here is an album which is based on one of our custom components that we're gonna look a little bit more about how we actually define that. But you can still use things like divs and links and image tags and the markup that you're familiar with in your JSX. And then here we're passing in some properties or props. So we have the artist name, title, cover image all that good stuff. And for our props and then also state that we'll talk about in a bit. When any of that changes, React is going to automatically re-render the component or any children inside of it or at least it will determine whether or not it needs to re-render them. So we can just go ahead and make some changes here and see them updated on the fly. So I'll go back to our friend Kenny Loggins and I found prepping this talk that it's pretty fun if you change dam to darn as a Kenny Loggins album. And so it could be a string value that gets passed in here in integer but also very commonly a variable and object and array, something like that. So I can just take this war cover image variable and then change my cover image here to curly braces if I can do that right. And war cover. Now I see the Warren Drugs cover for Kenny Loggins is darn. So let's look at defining the album component itself. This is album.js, it lives in source slash components. And we're importing React and then prop types. We'll look at prop types down towards the end and we're extending the React component class. There's a handful of different ways that you can define components in your React code here. Some of them are a little bit more streamlined and straightforward, especially if you have like a purely functional component. But I find that extending the React component class is kind of a good catch-all for examples, which is why I use it. And then you implement a render method here and it's going to return JSX as we've seen. There's a little bit of logic here. We're saying if there is a cover image, we're gonna render out a slightly different version of the album component than if there is no cover. And then we see things like album row. So you can think of that as being a custom component that we've defined. There's a little additional wrinkle to that that we'll get to. But then also you see things like image and div and H4. And then we're also referencing our props that are passed into our component. So we've got like this.props.artist and this.props.title. So we're taking the props and rendering them out. And then also in our album row, there's an onclick handler here. So if the album gets clicked, then we're calling a function that updates the styling of the album row and then populates the detail panel on the right-hand side. And that's also a function that's passed in as props as well. So you can pass down functions as props too. And then another thing to note about props is that props are immutable. So the component can't change them. I think of them kind of as external influencers on our component. Something is telling the component, you're this now, and it knows how to respond accordingly to them. And then there's prop types down at the bottom. It's just a simple way that we can kind of validate some of the props that get sent in, making sure a string is a string, a function is a function. And then we are exporting the album so we can import it elsewhere. So now let's talk about state a little bit. So again, the props are kind of the external influencers. I think about state more as what the component knows to be true about itself. Kind of deep and heavy. But it's data and variables that you can set inside the component that the component can modify. So this is just a little simple strip down example of some of what's happening in the control panel. So there's a couple of select lists that let you change the sort order and all that good stuff. So if I change the value here to average, I see that the select list now says average and it says the value here, the state is field average. So here's how that happens. If you want to define some states, you can define a constructor. Then we define a couple of constants for the default values for that, and then we set our state. So we say this dot state and provide selected sort and selected list. And then below that I'm binding a couple of functions. I usually use arrow functions to handle that and it handles the binding automatically, but for this preview panel, I had to do that binding. We'll skip over these two functions here for a second and get back to them, but let's look at the render method. So again, we're returning JSX. There always needs to be a single parent element that gets returned. That's why it's wrapped in a div. In more recent versions of React, I believe there's the concept of a fragment that lets you avoid having to have something like a wrapping div there. And then there's some markup, but we're also like in these paragraphs here, access of our state. So we're saying this dot state, dot selected sort to display the current value of selected sort from state. And then we have our select list and we're setting the value of the first select list to the value for selected sort in our state. And then we have an on change handler here. So we're calling that handle sort change function if the select list changes. And then really all we're doing there is setting the state. So the event gets passed in and then we're saying this dot set state and specifying that selected sort is gonna be set to the value that was selected in the select list. So all of that to do this. But it kind of demonstrates in a visual way state. And again, it's kind of the internal representation of the component. So now I know about props and state and I'm starting to build some components. And when I do that, I kind of ask myself, does this component need to have props? So take the props or state, take the album component, I look at that and I see that it has an album cover and title artist and I think, okay, that's probably state that this album component is gonna have. So I define my state. And then I move on to something like the detail panel on the right hand side. And it's got other stuff, but I also realize it has a lot of the same thing. So I probably initially I'm gonna say I'm gonna define some state here, but then I realize, okay, the state for the artist and title and potentially the cover, it's now in two places and I've got to modify that in two places, make sure it's all the same and up to date. And that doesn't feel right. And there's a common pattern in React about taking the state and lifting that up to a higher parent component. So if I follow that through, I might look at the cover visualization and say, okay, maybe that has some of this album state. But again, as I think that through, there's also the list visualization, the table visualization, they use all that same album data. And then even the control panel, it still has to know some stuff about the album state. It needs to know how many albums there are and how things are being sorted and stuff like that. So it eventually brings me to a point where it makes sense in this case to promote the state to the level of the app, basically the highest level component. And then that can be passed down to all of the children components inside of it. So let's see what that looks like in practice. So this is a snippet from the render method from app.js. So the album state is actually defined here. So when we have our snippet for the visualizations component here, we're passing in albums as props, but we're passing in the state because the app has access to the state. So we say this.state.active albums. And then if we go one level deeper and look at visualizations.js, that has the three tabs for the different visualizations. So we're still passing the albums through here, but in this case, they're props that are provided to the visualization component. So we're just, we keep passing it down. In this case, this.props.albums. And then we get one level deeper to the cover view component. And that is actually what starts to render out all of the albums. So we can take those album props and iterate through them and write out all of the albums. So that's kind of what it looks like as we pass those props down. You can also pass functions down so they can modify state as parent. And people who might be, have more experience with React or even attended the kind of introduction to React design patterns talk might be thinking to themselves that this might be something that you would use a library like Redux. Redux lets you manage your state kind of app-wide in a consistent manner. So that's something that I definitely look at the next time I make modifications to this. I think potentially the state here in this app is complicated enough that it might warrant that. And also React moves really fast in React 16.3, which I think is the most recent release of React. There's a new context API, which does some similar things where you can define state at a higher level component that other components can access without you having to pass it all the way down. So there's definitely things I'd look at doing differently there in the future. And maybe by the time I do it, React will change again and there'll be a new way to do it. Okay. So now let's talk about CSS in JS. So that was something that once I kind of started looking at what people were doing here, I understood what was happening, but I was absolutely flabbergasted. So let's talk about how we style this stuff. So you definitely can create a CSS style sheet and import it into your component. This is the control panel component in this case. And then when you do that, you can reference your classes with the class name prop, not class, but class name. And then the components will be styled as you expect. And that is fine. There's nothing wrong with that. But I'm trying to learn as much about React as I can, immerse myself here. I'm realizing that all the cool kids are writing CSS in JS. And it's definitely a bit of a face palm for me, especially when I see how it's done. This is like a candid picture I took one morning of my son when my wife was away. I just wanted to send her a picture. I'm like, yeah, here's how Colin's doing. And then this is what I got. And I'm like, I can't send that to her. She's gonna wonder what's going on. But definitely how I felt when I first saw CSS in JS. So the approach that I've taken with this is using styled components. There's a handful of different ways you can do it. But I've used styled components. So I'm importing styled and CSS from styled components. And then when I do that, I can define a constant here, which is a custom component, the album row, but it's a styled component. So I say album row is a styled div. Could be any other HTML element you're familiar with. But then also you can use your custom components as well if you want to style them as a styled component. And then you can write your CSS in line in your JavaScript with wrapped in those back ticks. You can also do SAS like nesting here, which is nice. Sometimes the syntax highlighting is a bit of an issue. I'm sure there are ways around that that I'm not familiar with. So it's nice that I do have my CSS in one place in the component, although feels very foreign initially. But also you can do things like respond to props in your styles here, which is actually pretty powerful. So this is a really simple example, but based on the active album prop, if that gets passed in, then I'm gonna change the border of this album row styled component and make it blue. So that's how when we click on those rows, they turn blue. And if you're doing this with jQuery, you typically will have to juggle class names on an HTML element and that gets the job done and works fine. But it actually makes a lot of sense that this component knows about its props and it knows more about itself. Why can't it just react to that? React, great, nailed it, Brian. And then style itself accordingly. And then, yeah, that album row that we talked about before. You can still think of these things as custom components and use them as custom components, but really in this case it's a styled component that doesn't look much different in the JSX. So this image is not something that I created myself. I'm sure some people have seen this before, but part of the reason that this feel felt weird and awful to me when I first started doing it is that I was taught a particular separation of concerns and JavaScript and CSS and HTML are kind of separate things that aren't really supposed to intermingle. And as you start building components this way, it feels like there is a different separation of concerns. So the album component is really where the separation is. And now instead we have that album component, which is a nice wonderfully packaged thing that has our JavaScript, our styles, and our markup as JSX. And we know how that album component is supposed to behave and we can use it together with other things. And as I build and react with components this way, that separation of concerns actually makes a lot of sense. The great thing is now I can go back between React and Drupal and always feel weird and wrong and awkward. So it's great. So let's talk a little bit about building and deploying. So where can I go, go, go. So we talked in the beginning about how that this is within the Jamstack. So let's review what our hot Jamstack is in this case. For JavaScript, we've got React on the client side. Our API is Drupal and we can host that anywhere that we can Drupal. I'm sure there's a lot of people who know where you can Drupal in this room. And if not, probably a lot of people out there. And markup. And so in this case, it's the production bundle that I generated. I'm just hosting it on GitHub pages. It's the static bundle. There's a ton of different places you can put that. It's not so static. We saw the spinner when we loaded the page initially. It's more kind of in the neighborhood of a single page application. But it still falls into this category. But as I learned more about the Jamstack, built out this application, I feel like the kind of secret sauce of the Jamstack is that concept of static markup and making things static. So think about static site generators in general. Or there's also one Gatsby.js for React that I've used that's pretty awesome. There's a webpack plugin that Gatsby is built on that you can use even without Gatsby to create static React apps. And yeah, I think that's where a lot of the power is. So you can think about the speed of things that are generated statically. Hosting options, putting on a CDN, the fact that you don't necessarily have to have your admin API accessible or as obviously accessible, take some of the security pressure off in some cases. So what I would encourage people to do if you build something that uses the same stack is to really try to challenge your perceptions about what can and can't be static, what dynamic means, and even take this app as an example, I can ask myself, could more of this app be static? Yes. But yeah, so just keep asking yourself those questions. So the first one I'd think about is I punted on routing or rooting as people have been joking about this week for people to say it differently. I just didn't get to that. And so I only have a single entry point into this app. It's always gonna be the first 50 albums ranked by their consensus score. So there's no reason that that couldn't be static. And then when the app loads, it's gonna get the data from the API behind the scenes, hopefully quickly enough that it's there when people start filtering. I'm sure there's ways to handle that. So that's a big difference in the initial load. We'd eliminate the spinner altogether. But then if you keep challenging your perceptions there, if I keep doing that, there's actually really only a month out of the year where this data is changing. It's December when all the lists get published. So it's nice that when that happens, we can hit it dynamically. But for the rest of the year, and especially now in 2018, the 2017 data is not gonna change. And if it does, I don't care. So there's actually, and again we have the assumption here that 2017, the data set is small enough that it's gonna perform reasonably. Based on that, there's actually no reason that this entire app couldn't be generated statically. And we're just gonna use the data from our Drupal API at build time. And then we have an asset that has all the stuff. We just deploy it wherever we want. And we're only gonna talk to Drupal again the next time the data changes. And that changes the game quite a bit as far as what we can offer, where we can deploy it, how fast it can run. So last thing, check in time, doing pretty good. So let's get to some hot melodrama care of Lord here. A question that I kept asking myself throughout putting this project together is did I need Drupal for this project? And the answer to that is no. But it's a qualified no. So I would say that if you are somebody who is, a JavaScript developer and has an answer for how you'd spin up an API like this, maybe you could do it with Express or something like Firebase or my fifth birthday party.js. I don't know. I don't know how you do it. But if you have a way that you can do it and you're comfortable with it, by all means use that and build your React app to talk to it. But I didn't wanna spend time on that piece of the puzzle. I wanted to learn more about React. So for me, it actually was a yes. I found that it was really easy to spin up an API thanks to Drupal with those two couple distributions. So I would say that if you are familiar with Drupal and comfortable with installing Drupal, it could be a great option for an API and let you get into building a React app pretty quickly. And I'd also say that even if you're on a level playing field and maybe you don't have a way that you would spin up an API and it's not necessarily child's play to you to consider these two couple distributions because they worked really well for me. It was easy and fast. And it let me get to the building the app part of things, which is a big part of what we're looking to do here. So I think in that case, it can be a yes for more people than we would necessarily expect. So everybody come to the sprints on Friday. They're great for all, whether you're a newcomer or a grizzled veteran. I will be there working on a component-based theme. I'm trying to get some more progress going forward, but in general, feel free to track me down. Love to talk more about this stuff. Sprints are a good time. So thanks. And also I do have some time for questions, which I cannot believe. Thank you. Go for it. Through your experience of learning React and kind of deciding Drupal sometimes, maybe Drupal not, when you are picking Drupal and you want React to come with like a custom module, right? You want it in some React front end. From your experience right now, would you say keeping that UI and that React code separate from the Drupal module itself, kind of like you have my jam module and then my jam module underscore UI, right? Would you separate them in that way or would you just bundle it together in the same thing or how would you actually approach that to kind of have that separation a little bit, to keep it clean? Yeah, I think it depends a little bit on the flavor of decoupling you're gonna go with. And I went with fully decoupled and I think in that case it's kind of cleaner break. I did keep them in the same repository so I have a repository that has Drupal and then React but they're in different folders. How about like in the middle tier, like a hybrid or a progressive kind of solution? Yeah, so I really don't know because I haven't done a ton of that. I think that's a case where it might make sense for it to live in Drupal. In the projects where I've done things that are kind of on the decoupled side of things, the progressively decoupled side of things, it was an Angular app in that case and Angular does live inside of Drupal in its own module. I think the reason that we did it in that case is because it was the thing that all of the developers that we had would be the most comfortable with. So, any other questions, cool? Feel free if you think of more of track me down but this was fun, thanks. Awesome, thank you Ben. I do. The answer to the do I have a card question is not always yes but this time I got it. It would be open to it, sure. Cool, thanks. Not in this case because what React makes as the production bundle, it's just static assets so I use GitHub Pages. So, I mean I'm not managing GitHub Pages, I just deployed it to a GitHub repository. So, I did have to manage the Drupal server but because what the jam stack is gonna get on the client side is static. It's, there's so many different places where you can use it. So, yeah, you can do that. There's no reason you couldn't do that. Thank you. Thank you. Yeah, as always. Like, close on both, have a look at your different things. Cool, thank you. Thanks for coming. Any other quick questions? I'm sure there are some questions. Mm-hmm. That would be a good one. Okay, thanks. Thanks a lot. I hope you'll be able to take that session there. I hope you'll be able to take that session there. I hope you'll be able to take that session there. Yeah. So, I haven't done that. I built a custom solution. Mm-hmm. Yeah, I mean, I think as far as authentication in, I think, in Contenta and maybe some of the reference applications that might be an example of that. So, on the authentication side, I think there are some examples out there. As far as just the general application state, a lot of that, as I understand it, can be done through our network. So, people are definitely doing that. In this particular case, I didn't, but there are, that's more the progressively decoupled case where, you know, it might be a block and a Drupal page, and they're making the exact opposite of what they're doing. People are definitely doing that. Although there are cases where people want to take the couple approach to have a little bit more flexibility in the developer experience, but people are totally doing that. Yes, thank you. Hey, nice to meet you. Thanks. Yep, yeah. So, the thing I haven't really set up all that much in the document is the Drupal side. So, what you can do really easily is, all the Drupal code is there and you can install it. The actual migration, the fire is like a Spotify. No, it's pretty easy, yeah. They don't know. Do you want to try to document a little bit about it? But also, there will be outside of things. You can just pull down the repository, and you can go and install it, and then you can start. It's going to hit my GVNC program line. So, you can play with it directly. So, what you do is then you type on that. That's what I put on GVNC. You can still run all that stuff locally. You can also run it on the Hotspot. I use Dreadable, yeah. Cool, yeah, no problem. Thanks for coming. Hey, I'm Jeff. No problem. Happy to be here. I've got some of the stuff out of your way here. Yeah. Yep. I don't think I've met her, no. We do a bunch of... Yeah, follow the... Yeah, I was wondering... Happy, and also kind of not surprising. That's what I was going to eat this time. Nice. I enjoyed the lunch here, too. And then it was music-related. Yeah, yes. It's nice to have fun. Yeah, I'd be happy to help on this. Did I, like, enter your mail? Yeah. Perfect. No problem. Send me an email. You? Yeah, please. See you around. How's it going, sir? It's going all right. How's it by you? Yeah, I got through my talk a lot. You know, I intended to watch it, but it was packed. It was jam-packed. Good problem. I can leave anything on the stand there. There was a clicker, which I put down here. Oh, cool. Okay. No, not that I heard. All right, I'll be here. Good luck. Thank you. Take care.