React app - building off Ravenous, using another API


#1

Hey everyone,

Just wanted to share what I’ve been working on. I was excited to finish the Ravenous project and immediately wanted to build my own app. Being the nerd I am, I picked interacting with the Dungeons & Dragons SRD API (the material that the owners of D&D will let people use without violating copyright).

Component Pouch: App for quickly listing the spell components for D&D spells
Code: https://github.com/nicholasarnold/component-pouch
Live Demo: https://nicholasarnold.github.io/component-pouch

A feature that I’m pretty proud to have figured out on my own:

  • When you type in a D&D spell into the search bar, it auto-suggests what you might be looking for (uses the onChange event to filter() the list of D&D spells array using the value of the input element)

Some bugs that I am aware of:

  • In src/components/SpellSuggestions/SpellSuggestions.js – The onClick event works on the button and for text inside button, but the target shifts to the image when the image inside the button is clicked; this causes a fatal TypeError. Any thoughts on how to prevent this?
  • In src/util/SRD.js – API requests use fetch() which doesn’t work on every browser or device; so this app won’t work on every device.
  • The app itself doesn’t appear very well on narrow devices (like my iPhone), so I need to figure out how to style things differently (I’m using the Bootstrap CSS framework for now).

Some questions for the community:

  • It seems we’ve learned several different ways to do styles in React. Ravenous uses actual CSS files, and then we learned how to do styles in JSX. How do you decide which method to use?
  • I ended up putting images in an images folder in src. I found that if I tried to stick them in the public folder, I couldn’t access them. The Ravenous project hosted images on AWS, but what is the typical way to host them locally?
  • One thing I admittedly did NOT do was separate my components between presentational components and containers. I was afraid of creating a really convoluted tree passing props and values up and down components, but I am curious to know if that’s what bigger projects do and if I should just get used to it.
  • I found out that using arrow functions inside component classes automatically binds this. Are there any side effects I need to be aware of?
  • Also, I learned that you can store information in custom attributes in elements on the DOM, but is that reliable? This is how my script knows which D&D spells to move from suggestions to selected and visa versa.
  • I noticed several functions did very similar things, and I’m not sure if it’s worth combining those functions into one and using parameters to determine what they do, or if having two separate functions is better… or if it’s just a preference. For example:
removeFromAvailable = spellId => {
  const removedSpellArray = this.state.spellsAvailable.filter(spell => spell.id !== spellId);
  this.setState({ spellsAvailable: removedSpellArray });
}

removeFromSuggestions = spellId => {
  const removedSpellArray = this.state.spellsSuggested.filter(spell => spell.id !== spellId);
  this.setState({ spellsSuggested: removedSpellArray });
}

They’re almost identically except the state they are updating. Merge? Keep separate?

Features I’m hoping to add:

  • When you click on a suggested D&D spell to add to your list of results, have a note saying the API is loading or have a loading animation; right now it can appear to lag.
  • If you type in the name of a D&D spell that you’ve already added, it appears as if the spell can’t be found; let them know the spell has already been added.
  • Cool CSS fade effect for suggestion list when overflowing the div (like what you see on paywall news sites)

Any other feedback, including tips on code readability, or faster ways to accomplish things are appreciated! Most of the functions are in src/Components/Main/Main.js.

Nick