Day 1: title formatting coherence, other edits

This commit is contained in:
Elizabeth Craig
2019-03-05 02:20:22 -08:00
parent 886738d12a
commit 8c99c83353
17 changed files with 133 additions and 104 deletions

View File

@@ -37,17 +37,12 @@ At this point, your VS Code window should look something like this:
<img src="https://user-images.githubusercontent.com/1434956/53654442-9c379400-3c02-11e9-8768-d19e092b606d.png" width=500 />
To start the dev "inner loop" for the first three lessons, run:
To start the dev "inner loop," run:
```
npm run static
npm start
```
When we get to lesson 4 and React, we'll stop the static inner loop (press `ctrl + C`) and instead run:
```
npm run start
```
Both of these commands will load the site shown below.
This will load the site shown below.
<img src="https://user-images.githubusercontent.com/1434956/53656239-88426100-3c07-11e9-8456-e3d958aa4def.png" width=500 />

View File

@@ -1,4 +1,6 @@
# How the Web Works
# Step 1.1 - Introduction to HTML (Demo)
## How the web works
A simple web page is rendered on the screen via the following steps.
@@ -21,7 +23,7 @@ A simple web page is rendered on the screen via the following steps.
![MDN Page Load](https://user-images.githubusercontent.com/1434956/53033758-9da8d580-3426-11e9-9ab8-09f42ccab9a8.png)
# HTML Demo
## HTML demo
HTML tags are the basis of all web applications. They give the page structure and define the content within.
@@ -35,7 +37,7 @@ HTML tags can also be nested to create a tree that we call the [Document Object
The [HTML demo page](https://microsoft.github.io/frontend-bootcamp/step1-01/demo) shows a large collection of HTML elements that you will come across during development. The full list of elements can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element).
## Sample Website
## Sample webpage
```html
<html>

View File

@@ -1 +1,3 @@
Readme is in index.html
# Step 1.1 - Introduction to HTML (Exercise)
See index.html from [npm start](http://localhost:8080/step1-01/exercise/) or the [live site](https://microsoft.github.io/frontend-bootcamp/step1-01/exercise/) for the exercise.

View File

@@ -1,6 +1,6 @@
## CSS Demo
# Step 1.2 - Introduction to CSS (Demo)
### CSS Properties
## CSS properties
Now that we've gone over adding HTML tags to the page, let's cover adding styles to those tags. We can do quite a lot with styles! We can change:
@@ -15,7 +15,7 @@ Now that we've gone over adding HTML tags to the page, let's cover adding styles
CSS styles are always written in `property: value` pairs (like `background: blue;`) and terminated with a semicolon.
### Applying CSS to an HTML file
## Applying CSS to an HTML file
CSS can be applied to HTML tags in three different ways.
@@ -25,7 +25,7 @@ CSS can be applied to HTML tags in three different ways.
3. Through an external CSS file
- `<link rel="stylesheet" href="./css-demo-finished.css" />`
### Targeting specific elements
## Targeting specific elements
Inline styles are always applied directly to the element you place them on, but `<style>` tags and external CSS files need a way to match elements with their respective style sets. This is done with **[CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors)**. When selectors are combined with CSS styles, we call this a **ruleset**.

View File

@@ -0,0 +1,3 @@
# Step 1.2 - Introduction to CSS (Exercise)
See index.html from [npm start](http://localhost:8080/step1-02/exercise/) or the [live site](https://microsoft.github.io/frontend-bootcamp/step1-02/exercise/) for the exercise.

View File

@@ -10,22 +10,22 @@
data-default-tab="html,result"
>
<pre data-lang="css">
/* 1. */
/* 1. */
/* 2. */
/* 2. */
/* 3. */
/* 3. */
/* 4. */
/* 5. */
/* 5. */
/* 6. */
/* 6. */
/* Bonus */
</pre>
<pre data-lang="html">
&lt;!-- Without changing the below markup apply the styles asked for in the markup. Do not apply styles that a tag doesn't ask for -->
&lt;!-- Without changing the HTML markup, apply the styles asked for in the markup. Do not apply styles that a tag doesn't ask for. -->
&lt;section&gt;
&lt;h2&gt;1. Text Color: Red&lt;/h2&gt;
@@ -38,7 +38,7 @@
&lt;/ul&gt;
&lt;div class=&quot;myClass&quot;&gt;4. Background Green&lt;/div&gt;
&lt;div class=&quot;myClass otherClass&quot;&gt;
5. Background Green &amp; Color White
5. Background Green &amp; Color White
(Hint Qualified Selector)
&lt;/div&gt;
&lt;div id=&quot;myId&quot; class=&quot;otherClass&quot;&gt;6. Background Yellow&lt;/div&gt;

View File

@@ -1,4 +1,4 @@
# JavaScript Demo
# Step 1.3 - Introduction to JavaScript (Demo)
It's entirely possible to create a website with nothing but HTML and CSS, but as soon as you want user interaction other than links and forms, you'll need to reach for JavaScript, the scripting language of the web. Fortunately, JavaScript has grown up quite a bit since it was introduced in the '90s, and now runs just about everything: web applications, mobile applications, native applications, servers, robots and rocket ships.
@@ -20,7 +20,7 @@ By the end of the demo we'll have covered the following:
- Loops
- Interacting with the DOM (Document Object Model)
## Introduction To Variables
## Introduction to variables
We can create a new variable with the keywords `var`, `let`, `const` and use them within our application. These variables can contain one of the following types of values:
@@ -35,7 +35,7 @@ We can create a new variable with the keywords `var`, `let`, `const` and use the
> [When to use `var`/`let`/`const`?](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable-in-jav) Use `const` for variables you never expect to change, and `let` for anything else. `var` is mostly no longer used. See the link for more details about how each works.
### Variable Examples
### Variable examples
```js
const myBoolean = true;
@@ -50,7 +50,7 @@ const myFunction = function(myNumberParam) {
> JavaScript is a dynamically typed language, so if you initially store a number in a variable (`let myVar = 0`), you can change it to contain a string by simply writing `myVar = 'hello'` without any trouble.
### Adding Variables
### Adding variables
Let's start off our demo by adding a variable to our [script tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script). This variable will be global and constant.
@@ -76,7 +76,7 @@ Functions on their own don't have any effect on the page. When I declare `functi
To execute a function we need to attach it to an event. There are a number of possible events: keyboard strokes, mouse clicks, document loading, and more.
### Add Event Listeners
### Add event listeners
To attach a function to an event, we use an [`addEventListener`](https://developer.mozilla.org/en-US/docs/Web/API/EventListener) like this:
@@ -92,7 +92,7 @@ window.addEventListener('click', function() {
> [`window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) is a reference to the entire window containing the HTML document.
### Global Event Handlers
### Global event handlers
If you think this feels a little verbose, you're not alone. Many of the [most common event types](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers) are available as element properties. This way we can set properties like `onload` or `onclick` like this:
@@ -208,7 +208,3 @@ function displayMatches() {
document.querySelector('.submit').value = matches + ' matches';
}
```
## Next Step
[Start our Todo App](../../step1-02/demo/)

View File

@@ -1,11 +1,3 @@
# Exercise
# Step 1.3 - Introduction to JavaScript (Exercise)
1. Create a function named `getFavs`. Inside, run `alert('clicked')`.
2. Create a variable `button` and set it to a reference to our button by using `document.querySelector('button')`
3. Add a click event listener to the button that calls `getFavs`. Click the button and make sure the alert is displayed.
4. Replace the `alert` call with a new `favList` variable set to an empty array: `[]`
5. Create a const variable `inputs` set to all of the inputs on the page. [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) will help here.
6. Iterate over all of the inputs using `for (const input of inputs) {}`
7. In each iteration, use an `if` statement to check if `input.checked` is equal to true
8. If the above tests passes, push the `input.parentNode.textContent` onto the `favList` array by passing the text as a parameter to `favList.push()` ([`push](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) is a built-in array method.)
9. Outside of the for loop, use `document.querySelector('.favorites')` to target the div at the bottom of the page. Set the div's `textContent` to `favList.join(' ')`. This will join each of the foods together into a string separated by a space.
See index.html from [npm start](http://localhost:8080/step1-03/exercise/) or the [live site](https://microsoft.github.io/frontend-bootcamp/step1-03/exercise/) for the exercise.

View File

@@ -28,16 +28,33 @@ button {
&lt;div class=&quot;favorites&quot;&gt;&lt;/div&gt;
</pre>
<pre data-lang="js">
/*
1. Create a function named `getFavs` and set its contents to `alert('clicked')`
2. Create a variable `button` and set it to a reference to our button by using `document.querySelector('button')`
3. Add a click event listener to the button that calls `getFavs`. Click the button and make sure it calls our alert.
4. Replace the alert with a new `favList` variable set to an empty array: `[]`
5. Create a const variable `inputs` set to all of the inputs on the page. `querySelectorAll` will help here
6. Iterate over all of the inputs using `for (const input of inputs) {}`
7. For each iteration use an `if` statement to check if `input.checked` is equal to true
8. If the above tests passes, push the `input.parentNode.textContent` onto the `favList` array. Pass that text into `favList.push()` as the parameter to add it to the array
9. Outside of the for loop, use `document.querySelector('.favorites')` to target the div at the bottom of the page. Set the div's `textContent` to `favList.join(' ')`. This will join each of the foods together into a string separated by a space.
/*
1. Create a function named `getFavs`. Inside, run:
alert('clicked')
2. Create a variable `button` and set it to a reference to our button using:
document.querySelector('button')
3. Add a click event listener to the button that calls `getFavs`.
Click the button and make sure the alert is displayed.
4. Replace the `alert` call with a new `favList` variable set to an empty array: []
5. Create a const variable `inputs` set to all of the inputs on the page.
`querySelectorAll` will help here.
6. Iterate over all of the inputs using:
for (const input of inputs) {}
7. In each iteration, use an `if` statement to check if `input.checked` is equal to true
8. If the above tests passes, push the `input.parentNode.textContent` into the `favList`
array by passing the text as a parameter to `favList.push()`
- `push` is a built-in array method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
9. Outside of the for loop, use `document.querySelector('.favorites')` to target the
div at the bottom of the page. Set the div's `textContent` to `favList.join(' ')`.
This will join each of the foods together into a string separated by a space.
*/
</pre>

View File

@@ -1,4 +1,4 @@
# Step 4 - Introduction To React Demo
# Step 1.4 - Introduction to React (Demo)
In this demo we'll be creating a simple counter that will display a count and increment on click.
@@ -19,7 +19,7 @@ The first parameter to `render()` looks a lot like HTML, but actually, it's [JSX
- Controls can be self-closing: `<MyControl text='hi' />`
- You can use JavaScript inside of JSX!
## Writing a React Component
## Writing a React component
A React component is a piece of code that returns a portion of your application. This can include HTML markup, CSS styles, and JavaScript driven functionality.
@@ -87,7 +87,7 @@ const App = props => {
};
```
### Destructuring Props
### Destructuring props
Writing `props.text` over and over in a function (or `this.props.text` in a class) can be quite tedious. Since this is all JavaScript, you could create a new variable for this text using variable assignment.
@@ -159,13 +159,13 @@ ReactDOM.render(<App />, document.getElementById('app'));
> Note the capitalization of `Counter`. HTML might not be case-sensitive, but JSX is! A common practice is to use the capitalized names of HTML elements to name corresponding React components: Button, Select, Label, Form, etc.
## React State
## Writing a stateful Counter component
React allows each control to specify its own data store, called **state**. We can reference values in state when we render our UI, and we can also update state over the lifetime of our application.
> Most stateful components you'll see today will be `class` based. It is just recently possible to add state to function components through the use of [`hooks`](https://reactjs.org/docs/hooks-intro.html)
### Adding State
### Adding state
JavaScript classes use a `constructor` method to instantiate each copy of a class, along with any applicable state. Let's create a new component called `Counter` and give it a state containing a `clicks` property with a default value of `0`;
@@ -184,7 +184,7 @@ class Counter extends React.Component {
- The [`super()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super) function calls the constructor of the parent class (in this case `React.Component`).
- Our `counter` state value can now be accessed via `this.state.counter`. Later, we can update state by calling `this.setState({ counter: 1 })`.
### Creating our Counter
### Rendering our Counter
For our `Counter` component, the goal is to be able to track how many times the counter's button is clicked. We'll use the following markup.
@@ -201,7 +201,7 @@ render() {
}
```
### Writing our Button Click Handler
### Writing our button click handler
Our next step is to wire up the button to increment the `counter` in our component state.
@@ -235,11 +235,11 @@ Add a couple `Counter`s to our `App`, each with different text. Notice how they
## Moving this into our codebase
To scale our application we'll need to break up the file into smaller, reusable pieces. In this part of the demo we'll look at the `final` folder and how the JavaScript module system allows us to break up our components into a collection of files exporting their functionality.
To scale our application, we'll need to break up the file into smaller, reusable pieces. In this part of the demo we'll look at the `final` folder and how the JavaScript module system allows us to break up our components into a collection of files exporting their functionality.
### Module Exports and Imports
### Module exports and imports
Open up the `step1-04/final/components/Counter.tsx` and look at the `Counter` component.
Open up `step1-04/final/components/Counter.tsx` and look at the `Counter` component.
```tsx
export class Counter extends React.Component {
@@ -255,7 +255,7 @@ import { Counter } from './components/Counter';
> Note the `{}` wrapped around the import value. This is actually an example of destructuring.
#### Default Exports
#### Default exports
We typically use named exports, but it's also possible export a default value like this:
@@ -271,7 +271,7 @@ When we import the component we can call it whatever we want:
import SomeCounterComponent from './components/Counter';
```
## Using a Button component
## Writing a Button component
Buttons are among the most commonly written components. Custom buttons help abstract common styling, add icons or other decorations, and increase functionality (menu buttons etc). Let's take a quick look at a custom button component to see how it comes together.

3
step1-04/final/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Step 1.4 - Introduction to React (Final)
Take a look at the contents of the `src` folder to see final versions of the `App`, `Button`, and `Counter` components from this lesson.

View File

@@ -1,19 +1,19 @@
# Step 1-05: Demo Building a Static Page
# Step 1.5 - Building a static page in React (Demo)
To start off our todo application we are going to follow the steps outlined in [Thinking in React](https://reactjs.org/docs/thinking-in-react.html). The first step of the process is to break our application into a component hierarchy. For this app, we're going to keep it simple and just use four parts.
To start building our todo application, we'll follow the steps outlined in [Thinking in React](https://reactjs.org/docs/thinking-in-react.html). The first step of the process is to break our application into a component hierarchy. For this app, we're going to keep it simple and just use four parts.
- TodoHeader
- TodoList
- TodoListItem
- TodoFooter
You can find the HTML for our application in `step1-05/TodoApp.html`
You can find the HTML for our application in `step1-05/TodoApp.html`.
## TodoHeader
We are going to store all of our components inside of a `components` folder. Lets create that now. We'll then start with the `TodoHeader` inside of a file called `TodoHeader.tsx`. This file format tells our application that this file includes React code written in Typescript.
We'll store all of our components inside a `components` folder under `src`. Let's create that now. We'll then start writing the `TodoHeader` in `components/src/TodoHeader.tsx`. The `tsx` file extension tells our editor that this file includes React code written in TypeScript.
> We'll talk about Typescript soon, but for now know that all valid JavaScript is valid Typescript
> We'll talk about TypeScript soon, but for now, know that all valid JavaScript is valid TypeScript.
```jsx
import React from 'react';
@@ -38,7 +38,7 @@ export class TodoHeader extends React.Component<any, any> {
}
```
> Note that since this is React we had to change `class` to `className`, but nothing else changes.
> Note that since this is React, we had to change `class` to `className`, but nothing else changes.
## TodoListItem
@@ -60,4 +60,15 @@ export class TodolistItem extends React.Component<any, any> {
}
```
> Note that this control could also be created as a function instead of a class: `export const TodoListItem = (props) => {}`
> Note that this control could also be created as a function instead of a class:
> ```jsx
> export const TodoListItem = (props) => {
> return (
> <li className="todo">
> <label>
> <input type="checkbox" /> Todo 1
> </label>
> </li>
> );
> }
> ```

View File

@@ -1,16 +1,20 @@
# Step 1-06 Exercise
# Step 1.5 - Building a static page in React (Exercise)
### TodoFooter
From this exercise on, we'll be working in VS Code instead of CodePen. If you don't already have the bootcamp folder open in a VS Code window, see the [main readme](https://github.com/Microsoft/frontend-bootcamp/blob/master/README.md) for instructions.
1. Add a TodoFooter component in the `components` folder, copying over the `<footer>` tag and all of its children from `TodoApp.html` in the `step1-05` folder. This could be a function or class.
If you don't already have the app running, start it by running `npm start` from the root of the `frontend-bootcamp` folder. Click the "exercise" link under day 1 step 5 to see results.
## TodoFooter
1. Add a TodoFooter component in the `components` folder, copying over the `<footer>` tag and all of its children from `TodoApp.html` in the `step1-05` folder. This component could be a function or class.
2. Remove any `onclick` properties, and change `class` to `className`
### TodoList
## TodoList
1. Add a TodoList component like you did with the footer. This could also be function or class.
2. Import TodoListItem and add 4 of them inside of the `<ul>`
2. Import TodoListItem and add four of them inside of the `<ul>`
3. Bonus points for using a [`for`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration) loop or using [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) to create 4 list items based on the array `[1,2,3,4]`
## App.tsx
## App
1. Import both of these components into `App.tsx` and place their tags below the `TodoHeader`.

View File

@@ -1,12 +1,12 @@
# Step 1-06 Demo: Creating a State-Driven UI
# Step 1.6 - Creating a state-driven UI (Demo)
In React, the data travels in one direction: top-down in the form of state propagating down the component hierarchy. Only the component containing the state can change the state itself. When a UI interaction occurs, a stateful component must pass down an event handler to the UI component triggering the event in order to signal a state change.
[Step #3 of "Thinking in React"](https://reactjs.org/docs/thinking-in-react.html) suggests finding the "minimal set of mutable state" that your application requires. So in this demo we are going to add that "minimal state" to our application and drive our UI off of that data. With that done, the next step will be to create ways to modify that state, which will in turn cascade down through our UI. This [reconciliation](https://reactjs.org/docs/reconciliation.html) process, figuring out what in your UI needs to change based on changing state, is what React excels at.
## Adding State to `TodoApp.tsx`
## Adding state to TodoApp
Inside our `TodoApp` class, we will add the minimal state for our application, which includes just two keys: `todos` and `filter`. We don't need to worry about a `remaining` value because it can be calculated by counting the number of todos where the `completed` field is set to `false`.
Inside our `TodoApp` class, we will add the minimal state for our application, which includes just two keys: `todos` and `filter`. We don't need to worry about a `remaining` count because it can be calculated by counting the number of todos where the `completed` field is set to `false`.
So here is our full constructor:
@@ -39,7 +39,7 @@ constructor(props) {
> You could also use an array to represent your todos. Array manipulation can be easier in some cases, but this object approach simplifies other functionality and will ultimately be more performant.
## Passing State Through to UI
## Passing state through to UI
Now we can pass `filter` and `todos` into our components.
@@ -56,7 +56,7 @@ render() {
}
```
## State-Driven TodoList
## State-driven TodoList
I've already pulled out our props into `filter` and `todos` variables, and written a bit of JS that will return an array of filtered todo `id`s. We'll be using that filtered array to render our todo items.
@@ -72,11 +72,11 @@ return (
);
```
## State-Driven and Stateful Header
## State-driven and stateful TodoHeader
Within the header we've got a situation where we not only want to pass `filter` state down to it, but we also want to maintain state within the control. Fortunately, this is no problem at all for React. First off let's deal with the incoming state.
Within the header, we've got a situation where we not only want to pass `filter` state down to it, but we also want to maintain state within the control. Fortunately, this is no problem at all for React. First off let's deal with the incoming state.
### Conditional Class Names
### Conditional class names
In CSS-based styling, visual states are applied by adding and removing classes. We can use the filter value to conditionally add a class, thereby lighting up the correct filter button.
@@ -90,7 +90,7 @@ In CSS-based styling, visual states are applied by adding and removing classes.
> The [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) `condition ? expressionIfTrue : expressionIfFalse` is widely used in React code, as each expression could be a string for a className or even a JSX element.
### Adding a Controlled Input
### Adding a controlled input
In React, form elements such as `<input>`, `<textarea>`, and `<select>` can be used as either **uncontrolled** or **controlled**.

View File

@@ -1,11 +1,11 @@
## Exercise
# Step 1.6 - Creating a state-driven UI (Exercise)
If you don't already have the app running, start it by running `npm start` from the root of the `frontend-bootcamp` folder. Click the "exercise" link under day 1 step 6 to see results.
### TodoFooter
1. Use the provided `itemCount` value to display the current number of items left.
2. Use a ternary operator to print "item" vs "item**s**" based on whether `itemCount === 1`.
2. Use a [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) to print "item" vs "item**s**" based on whether `itemCount === 1`.
### TodoListItem

View File

@@ -1,30 +1,30 @@
# Types and Creating a UI-Driven State
# Step 1.7 - Types and creating a UI-driven state (Demo)
Now that we have a UI that is purely driven by the state of our app, we need to add functionality to allow the UI to drive the state. This is often done by creating functions that call `setState` like we saw in the `TodoHeader`. Values from the state are then passed down to the UI as props.
Now that we have a UI that is purely driven by the state of our app, we need to add functionality to allow the UI to drive the state. This is often done by creating functions that call `setState` like we saw in the `TodoHeader`. Values from the state are then passed down child components as props.
> We'll be learning in part 2 of this workshop how we can expose these functions without explicitly passing them down via props.
This is our core "business logic" and handles everything our basic "CRUD" operations: Create, Read, Update, Delete. We don't have time to walk through writing all of those functions, but you can see that they are already provided in the demo's `TodoApp` and passed into our components.
This is our core "business logic" and handles our basic "CRUD" operations: Create, Read, Update, Delete. We don't have time to walk through writing all of those functions, but you can see that they are already provided in the demo's `TodoApp` and passed into our components.
## Intro to TypeScript
Taking a look at our components in `TodoApp`, you can see that our list of props is not just getting longer, but is getting much more complex! We're passing through functions with various signatures, complex `todos` objects, and filter strings which are always one of three values.
Taking a look at our components in `TodoApp`, you can see that our list of props is getting not just longer, but much more complex! We're passing through functions with various signatures, complex `todos` objects, and filter strings which are always one of three values.
As applications grow, it becomes increasing difficult to remember what each function does, or what each todo contains. Also, as JavaScript is a dynamically typed language, if I wanted to change the value of `todos` to an array inside my `TodoList`, JavaScript wouldn't care. But if `TodoListItems` was expecting an object, our application would break.
As applications grow, it becomes difficult to remember what each function does or what each todo contains. Also, as JavaScript is a dynamically typed language, if I wanted to change the value of `todos` to an array inside my `TodoList`, JavaScript wouldn't care. But if `TodoListItems` was expecting an object, our application would break.
It for these two reasons that the entire industry is shifting to writing applications that are strongly typed, and many are using TypeScript to accomplish that.
For these two reasons, the industry is shifting to writing applications that are strongly typed, and many are using TypeScript to accomplish that.
As [TypeScript's website](https://www.typescriptlang.org/) states:
> TypeScript is a superset of JavaScript that compiles to plain JavaScript.
If you've ever used [Sass](https://sass-lang.com/) you are familiar with this concept. In the same way that all valid CSS is valid Sass, all valid JavaScript is valid TypeScript. That's why most of these exercises have been written in `ts` and `tsx` files instead of `js` and `jsx` files.
If you've used [Sass](https://sass-lang.com/), you're familiar with this concept. In the same way that all valid CSS is valid Sass, all valid JavaScript is valid TypeScript. That's why our exercises have been written in `ts` and `tsx` files instead of `js` and `jsx`.
Let's dive into the demo and see how TypeScript can help us better understand our component props and guard against future regressions.
Let's dive in and see how TypeScript can help clarify our component props and guard against future regressions.
# Demo
Let's start off in the TodoList, as that has the most data flow up and down. There isn't any interactive UI in this component, as we're simply passing `completed` down to each `TodoListItem`, but we can write a props interface for the component to make sure that everything gets passed down properly.
Let's start off in the TodoList, as that has the most data flow up and down. There isn't any interactive UI in this component, as we're simply passing `completed` down to each `TodoListItem`, but we can write a props interface to make sure that everything gets passed down properly.
## Writing TodoListProps

View File

@@ -1,12 +1,15 @@
#Step 1-07: Exercise
# Step 1.7 - Types and creating a UI-driven state (Exercise)
If you don't already have the app running, start it by running `npm start` from the root of the `frontend-bootcamp` folder. Click the "exercise" link under day 1 step 7 to see results.
## TodoFooter
1. Open TodoFooter and write a TodoFooterProps interface. It should include two values, a `clear` and `todos`. Use this interface in the function props like this: `(props: TodoFooterProps)`
1. Open TodoFooter and write a `TodoFooterProps` interface. It should include two values, a `clear` and `todos`. Use this interface in the function props like this: `(props: TodoFooterProps)`
2. Write an `_onClick` function that calls `props.clear`.
> Since TodoFooter is not a class, the `_onClick` function needs to be stored in a const placed before the `return`.
- Since TodoFooter is not a class, the `_onClick` function needs to be stored in a const placed before the `return`.
- Remember to use an arrow function to define this click handler.
3. Assign `_onClick` to the button's `onClick` prop. You won't need to use `this` since the component isn't a class.
@@ -14,13 +17,14 @@
## TodoHeader
1. Open TodoHeader and write TodoHeaderProps which will include `addTodo`, `setFilter` and `filter`. Replace the first `any` in the class declaration with this interface.
1. Open TodoHeader and write `TodoHeaderProps` which will include `addTodo`, `setFilter` and `filter`. Replace the first `any` in the class declaration with this interface.
2. This component also has state. Write TodoHeaderState (there's just one value), and add this where the second `any` was.
2. This component also has state. Write `TodoHeaderState` (there's just one value), and add this where the second `any` was.
3. Add `_onFilter` to each of the filter buttons
> Note that we can't add new parameters to onClick, but we can pull information from the event target!
- Note that we can't add new parameters to onClick, but we can pull information from the event target!
- Remember to use an arrow function for this one too
4. Call `_onAdd` from the submit button