It's been a while since I quickly knocked out something simple and I wanted to be sure I can still do it, so I decided to see if I can build a super simple app in less than an hour.
First I needed an idea. I couldn't think of what to do, but I was thinking of lots of other random things ... and so I got an idea. I would create an app that displays all of my random thoughts. The app would be one page, but have three "parts" - a card on top with my most recent thought, an area to input a new thought, and a list of my older thoughts on the bottom.
Now that I had an idea and knew what I wanted it to look like, it was time to write some code. Rather than create the whole thing from scratch, I used Create React App to initialize my app. With one command (npx create-react-app random-thoughts
), I was able to create the basic structure of my app in a few short minutes.
While Create React App was working its magic, I made a list of the things I needed to build:
- Input form
- Card with most recent thought
- List of older thoughts I didn't think it was practical to list all of the thoughts, so I decided to limit it to the 25 most recent thoughts.
Once my app had been created, I opened the code in a text editor (I used Atom for this, although I generally use Sublime Text) and wrote some pseudocode in the App.js file:
Once I knew what I wanted to write, it was time to start writing code. I started with the input form, because in order to display thoughts, I had to be able to input the thoughts. I decided that because this was a "quick and dirty" app, instead of storing the thoughts somewhere in a database, I would just store them in local state. Rather than create a stateful component just for this, I decided to use React hooks with my functional component to create a state in which to store my thoughts. I decided to keep the input form in the main app file, so I wrote a quick input form and the logic needed to save that input to state:
import React, {useState} from 'react';
import './App.css';
function App() {
const [thoughts, setThoughts] = useState([])
function addThought(e) {
e.preventDefault();
const newThought = e.target.thought.value
e.target.thought.value = ''
const allThoughts = [newThought, ...thoughts]
setThoughts(allThoughts)
}
return (
<div className="App">
<form onSubmit={addThought}>
<label htmlFor="thought">I'm Thinking...</label>
<input type="text" name="thought" id="thought" />
<button>Add New Thought</button>
</form>
</div>
);
}
export default App;
Next step was to display the thought I had just inputted. For this I created a separate component, which I called ThoughtCard
, which I placed in a components
folder:
import React from 'react';
const ThoughtCard = ({thought}) => (
<div style={styles}>
{thought}
</div>
)
const styles = {
color: 'green',
height: '33vh',
width: '33vw',
margin: '5vh auto',
fontSize: '3rem',
textAlign: 'center',
border: '1px solid darkgrey',
}
export default ThoughtCard
As you can see above, I also added some styles to ThoughtCard
to set it apart from the rest of the page. I decided to add the styles to the component file because I wanted it done quickly, and also because I didn't want to worry about scoping.
I also created an index.js
file for my components folder so that I could export all of my components together.
The next step was displaying the older thoughts. To do this, I created a MiniCard
component to display each thought, and then mapped over the list of thoughts (starting with the second item in the thoughts array, since the first item is already displayed as the most recent thought) and displayed each one as a card:
import React, {useState} from 'react';
import {ThoughtCard, MiniCard} from './components/index'
import './App.css';
function App() {
...
return (
<div className="App">
...
{
thoughts.slice(1).map(thought => <MiniCard thought={thought} />)
}
</div>
);
}
export default App;
import React from 'react';
const MiniCard = ({thought}) => (
<div style={styles}>
{thought}
</div>
)
const styles = {
color: 'blue',
width: '75vw',
margin: '3vh auto',
padding: '1vh',
fontSize: '1.25rem',
border: '1px solid lightgrey',
}
export default MiniCard
As you can see, the MiniCard
component is the same as the ThoughtCard
component except for the styles. I had originally planned to do the older thoughts as a list, not cards, which is why I separated them out, but my next step for this project is to get rid of the MiniCard
component, change the ThoughtCard
to accept styles as a prop, and use the same component in both places but pass it different styles.
And that was my app. Here's what it looks like when it runs:
All of this was done in about 49 minutes.
There is more work to be done on this app. The first step is to combine the ThoughtCard
and MiniCard
components into one component because right now there's a lot of repeated code there. I also want to work on the styling and make it more visually appealing.
There are also some faults with this app, especially the fact that storing thoughts in the state means they don't persist between sessions. So there's no way to know what you were thinking yesterday.
But this wasn't meant to be a perfect app ... it's just something I threw together in less than an hour. Just to prove to myself that I can.
Top comments (1)
Good read, and nice, clean, and simple code.