Intro to React State
#
Learning Objectives- Learn about state
- Learn how to declare state in a React component
- Learn how to iterate over some data and render it
#
StateState is the particular view of a React component based on its data.
We can imagine we have a component that has our shopping cart
At first, our cart is empty. Our state would likely be an empty array .
Then we add an item into our cart. We'd push an object like this one into our cart:
{ itemName: "Jar of Speculoos", description: "Imagine butter cookies dissolved in butter, made into cookie butter and stored in a jar. Stop imagining and now buy this!", price: 6.99,};
Now our view of our shopping cart will change, based on the data or the state of the shopping cart.
#
Set UpLet's build a tiny online store and render the items available to us.
npx create-react-app big_time_shopping
cd big_time_shopping
rm -rf .git
- because we are in the class repository - no git reps inside other git repos!- open a new tab in terminal
npm start
- in the other open tab
atom .
#
Make This App Our OwnLet's remove all the create react app showcase stuff and rewrite our component to be a class. There are a few ways to make react components. We're going to stick with classes. Later, when you feel more confident you can explore different ways to write them
import React from "react";
class App extends React.Component { render() { return <div></div>; }}
export default App;
#
Render a listcopy the contents of the data.js
in instructor_notes
and paste it on line 1 of your App.js
console.log to check that it looks right
We want to be able to see an unordered list of our product names in the browser.
React is designed to render views based on data.
Let's set up our React app.
#
App.jsclass App extends React.Component { render() { return ( <div> <h1> Big Time Shopping </h1> </div> ); }}
Currently, our app has no state (no view based on data). That's ok! Not all components have to have state. A simple navigation bar that is just 'hard coded' can be a react component - some components are just for presentation.
However, in the case of our online store, we'll want a list based on our data, so we will add state.
state
is a special key word in react. In order to use it, we have to set up our constructor
function. You cannot declare state without calling super. Try it! You'll get an error. Go back to your unit 1 notes for more details.
class App extends React.Component { constructor(props) { super(props); this.state = { products: products, }; }
render() { return ( <div> <h1> Big Time Shopping </h1> </div> ); }}
We can look at our React dev tools and now see that our products are being stored in the App
components state
Inside the return
of render()
function is special. The syntax that is recognized is JSX. JSX is a mishmash of HTML and JavaScript. We can't console log inside the return, and there are few little gotchas we'll see along the way.
Much like we did in unit 2, we can embed our data in the html. Let's put the first product in there for rendering. We have to wrap what we want to render in curlies {}
render() { return ( <div> <h1> Big Time Shopping </h1> {this.state.products[0].name} </div> );}
We should see the allen wrench show up.
Unlike EJS (or handlebars), we can't write for loops here. But what we can use is the .map
function. .map
will iterate over every item, manipulate it in some way and return the new array.
In our case, we want to make an unordered list:
render() { return ( <div> <h1> Big Time Shopping </h1> <ul> {this.state.products.map((product) => { return <li>{product.name}</li>; })} </ul> </div> );}
Note : You'll get a message in the console
Warning: Each child in a list should have a unique "key" prop.
This a warning and you don't have to fix it. We'll learn how to fix it once we are working with data coming from a database/API.
Remember, with ES6, if our function is one line of code (and no more), we can skip the curly braces after the arrow and we can skip the return statement - it will implicitly return the one line. However, if you don't put anything on the same line as a return statement it will return undefined/null - so be sure to add at least a parenthesis on the same line as the return.
In our case, we may also want to show the price, so let's update our code:
render() { return ( <div> <h1> Big Time Shopping </h1> <ul> {this.state.products.map((product) => { return ( <li> {product.name} {product.price} </li> ); })} </ul> </div> );}