Build Basic React App | Components / State *

https://medium.com/@nataliebarba/build-a-basic-app-in-react-part-i-9c6c27dbfc41

Build a Basic App in React, Part I

A couple of weeks ago, I wrote about beginning Flatiron School’s Software Engineering bootcamp.

This week we made the jump from learning Vanilla JavaScript to React. Though fundamental concepts are shared, perhaps the biggest difference between the two is the way that code is structured and data is shared. In this post, we’ll review components and props as we begin to build a basic to-do app in React.

Quick Overview

So what are components? React documentation states:

“Components let you split UI into independent, reusable pieces, and think about each piece in isolation.”

In other words, we want to split our app’s code into components that help us separate responsibilities. Components resemble Vanilla JavaScript functions and they return JSX.

What about props? Essentially, props are units of information we want to pass down from a parent component to a child component. We define the props keys and values within the parent component.

We’ll see examples of components and props below.

Set Up a Basic App

Assuming we already have React installed on our machines, all we have to do is run the following in terminal to get a basic React app started for us:

npx create-react-app to-do-list cd to-do-list npm start

What we did here was create an app called “to-do-list”, navigated to it, and opened it in our browser.

Let’s go ahead and open “to-do-list” in our code editor. We’ll see that there are a series of files already set up for us — we’re ready to start making this basic app ours.

Within the src folder, you’ll notice a file called App.js. This will be home base. Everything that we want rendered on our page will live here. Below is the default App.js, which we’ll change to make our own:

 

img

Make a Plan

Before we jump right into writing code, we should decide what our app looks like to help us break down our code into those components we talked about. Our app might look like:

 

img

According to this sketch, here’s one way we can structure our app:

  • Header component — to include our title (and a description if we’d like)
  • NewTaskForm component — a form that allows users to add new tasks (building this will come in a future post)
  • TaskList component— a collection of tasks
  • Task component— an individual task

We will need to create a separate .js file for each of these.

Before we do so, let’s create a data file with a few to-do items that we would like to render on the page when it is loaded.

Define Initial To-Dos

 

img

Within the src folder, create a file called todosData.js. Similar to how we may create a db.json file for a Vanilla JavaScript app, let’s create an array with to-do objects. These can be fairly simple, with only two properties: an id, and the text that describes the task. We’ll need access to this data later, so let’s be sure to export our array as above.

Create the Header

Now let’s build the app! First thing is first, we need a title. To get that set up and organized, let’s create a components folder within our src folder. This folder will house the components we previously defined. Within components, let’s create a Header.js file.

For this project, we will always set up our components by:

  • importing React
  • creating a function with the same name as the file component that will return JSX *In React, it is standard for components to begin with a capital letter, which differs from functions in vanilla JavaScript
  • exporting the function This will allow us to import the new component and use it in our App.js, which will render it to the browser

In our Header.js file, let’s start simple and return an

element with our title.

 

img

If you save and head over to your browser window, you’ll see that nothing has happened quite yet. That’s because we haven’t added this Header to our App.

Let’s got into App.js and give it access to our new Header file. To do so, we must add an import statement to the top of App, as below:

import Header from ‘./components/Header’;

Once that is done, we can use

in our App. Let’s replace the default code in our App.js as such:

img

img

If you take a look at your app in the browser, you should now see “My To Do List” at the top.

Define a Basic To-Do

Now let’s work on rendering a to-do on the page. We know that we’ll need to pass data in from our data file (ahem, perhaps using props) to create the to-dos we previously defined, but we can build a skeleton for what each to-do will look like now.

Let’s create a new file called Task.js in our components folder. We’ll set it up as we did our Header and customize.

We know we will want to display the to-do item, along with a button to mark the task as done. (We will add functionality to the button in a future post)

 

img

With the Task component defined, we can now work on creating our collection of tasks.

Create Our List

Let’s create a file called TaskList for this component.

Of course, our list is going to be a series of Tasks, so we have to import the Task component into our TaskList for use. For now, let’s start with adding a single Task just to see it rendered to the page.

 

img

Remember that we still have to import this to our App component. Let’s go ahead and do that as below.

 

img

If you take a look at the browser now, you’ll see our title, and a single todo.

Now that we see our components working together, let’s work on getting our actual to-dos from our data file on the page.

To pass down information from our App to our TaskList, we’ll have to pass them in as props. We can do this by adding a property and value inside of our .

 

img

Now over in TaskList.js, we’ll have to pass our props as our argument to pull that data through. We can either pass in as “props” and then refer to our data as “props.todos” within our component, or we can destructure our props as “{ todos }” (as we would any object) to simply refer to the data as “todos”. I selected destructuring in my example.

We’ll now have access to our todosData file in our TaskList component.

Okay, we know that we are going to want a Task component for each item in our todos. Let’s use map to accomplish this.

Remember that when we want to code in JavaScript within our components’ return statements, we must use { }.

To use map on an array, React wants us to give each result a unique key. We added unique IDs to each item in our list, so IDs will work perfectly as keys.

 

img

When you open the browser, you should now see three to-dos. Great!

Next, let’s get those three items to display our real to-do text.

Similar to how we passed our todos down to TaskList, we’ll want to pass a single to-do object to each Task. We already have a map that can help us with this, so we’ll just add a “todo” prop to our as below.

 

img

Update Tasks With Information

Back in our Task.js, we can’t forget to add the as a parameter for our Task below. Now we’ll have access to our to-do object, and can access the text to add within our

as below.

 

img

Conclusion

Now when you open your browser, you should see a title, and three to-dos. Nice work!

 

img

In Part II of this post, we review state as we build events that allow the user to add a new to-do and delete a completed to-do

 

https://medium.com/geekculture/build-a-basic-app-in-react-part-ii-c70e10f7e850

Build a Basic App in React, Part II

Natalie Barba

Natalie BarbaFollow

Sep 20 · 7 min read

 

 

 

 

 

 

It’s time to go over React state and incorporate it into the to-do app we’re building. If you haven’t already, be sure to check out Part I of this post which reviews React components and props as we begin to build this app.

Now onto state.

Quick Overview

So what is state? In React, state is dynamic data that changes as users interact with your application. The fact that state can change during a component’s lifetime makes it different from props — props rely on parent components to pass static information down to their children.

Note that in order to work with state in your code, you must import the React useState Hook. Now what is a Hook? React documentation describes it best. It’s “a special function that lets you ‘hook into’ React features.” For example, useState is a feature that was built for React class components. We are building our app using functional components, which don’t include the same features, but we can import the features we need, like useState, with a Hook . To learn more, be sure to check out the documentation.

Implementing useState looks as below:

import React, { useState } from ‘react’;

function Example() { // Declare a new state variable, which we’ll call “count” const [count, setCount] = useState(0); … }

On the left, we have two variables. First we have our state variable and second our setter function which updates our state. On the right, we set our state variable to an initial value that we decide. So for the example above, we initially set count to 0. Later, we can say setCount(5) to update that count to 5. We’ll see more examples in our code-along. Let’s get started.

Goals

We will add two key features to our to-do app:

  1. The ability to mark a task as complete, or “Done”, and remove it from our task list.
  2. The ability to add a new task

We will accomplish both by using state.

Planning Where State Lives

As we think through how we can accomplish our goals, we should ask ourselves, do we need to manipulate data? If so, which data?

Whether we’d like to delete an existing task or add a new one, we will need to manipulate the array that we iterate over in order to render each to-do element on the page.

We would like to change data according to user actions, within our component’s life. Sounds like state. Where should this state live? These four questions help us decide:

  • Identify every component that renders something based on that piece of state
  • Find a common owner component (a single component all components that need that state in the component hierarchy)
  • Either the common owner or another component higher up
  • If you can’t find a component where it makes sense to own, need a new component

Both TaskList.js and NewTaskForm.js will need to use this array that is updated by user actions. Though we created a file for our NewTaskForm component, we haven’t built it nor imported it anywhere, so let’s take a moment and take care of that.

NewTaskForm.js

We can create a very simple form by adding an input area for the new task and adding a submit button as below

img

img

Now we must import this into our homebase, App.js.

App.js

img

img

We know that our NewTaskForm won’t need access to our previously built data, todos, so there is no need to pass in props quite yet.

Planning State Continued

Now that we’re set up with all of our components, we can go back and determine where our state will live — the state for our to-do array that we will manipulate through user actions. As we mentioned, both NewTaskForm.js and TaskList.js will need access to this array, so we’ll want our state to live in their shared parent component, App.js.

App.js

Remember, if we want to use state, we must import the useState hook. Afterward, let’s create a state variable for that array of to-dos we keep mentioning. We’ll set the initial value of that array as the array we’re importing from todosData.js.

img

img

Let’s tackle one user action at a time, starting with the “Done” button click.

We know that when we click “Done”, we will want to remove an element from todoArray. We must create a function that manages this logic, and any time we create a function to manage a state’s manipulation, we should do so within the same component as we have defined state.

Let’s create a function called deleteItem that will take itemToDelete as a parameter. We’ll create a copy of our original todoArray, minus the item we would like to delete using the filter method. We can assume that no two to-dos will be exactly the same and filter based on the to-do’s text description. Finally, we’ll use our setter function to update our todoArray to our updated array.

Now, instead of passing down the original dataset, todos, down to TaskList.js we’ll want to pass down the array that updates with user actions, todoArray. We will also want to pass down our newly defined deleteItem function so that (eventually) our event handler function can invoke it. Our updated App.js should be as below:

img

img

TaskList.js

Here, we’ll need to update our destructured props accordingly. We’ll also have to update the array that we are mapping over to create Task components for each to-do. We won’t use the deleteItem function here, so let’s also pass that down to our Task component.

img

img

Task.js

Back in Task.js, all we have to do is add a click event listener to our button, which will execute the deleteItem function. We can create an event handler function that calls that function as below.

img

img

Now if you refresh your app in the browser and click on any of the “Done” buttons, that should get rid of a task.

*Note the changes will not persist in the app upon refresh. For the changes to persist, there must be communication to a server, which is not covered in this blog post.

App.js

Because we’ll be adding a new task to the same array that we already have a state for, we don’t need to create a new state. Similar to how we created a function to handle deleting a task, let’s create one for adding a task, back in App.js where our state lives.

We’ll follow similar steps: create a new array, use the spread operator to create a copy of our original array, then add our new item to the end of it.

We’ll need to invoke this function when a user submits a new task, which will happen in NewTaskForm.js, so let’s pass it down as props.

img

img

NewTaskForm.js

Before jumping straight into the submit activity logic, let’s make our form a controlled form.

“In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.”

We can do this by creating a state for our users input, after importing the useState Hook. Since todoArray is made up of to-do objects, we should follow that format and initialize our new state to an object with a “text” key and an empty string as its value. Let’s define our event handler function to update this state as the user types. As the last step, let’s add an onChange listener to our input text with this new function.

img

img

Now we can handle the submit.

Let’s create the function we’ll pass to our submit event listener. By default, a form submit refreshes our browser. We don’t want this, so we’ll start with preventing that default behavior. Next, we’ll add our state variable, which represents the object we created and updated based on the user’s input using state, to todoArray using the function we defined in App.js and passed down as props. Let’s reset our state and form to have empty values. Finally, we need to create an onSubmit event listener, using our newly created function as below.

img

img

Conclusion

You should now be able to open this up in your browser and be able to:

  1. See a title, a form, and a list of to-dos with buttons
  2. Remove to-dos by clicking “Done”
  3. Add new to-dos using the form

img

img

Nice work building an interactive React app and thanks for following along!

Geek Culture

Scroll to Top