mirror of
https://github.com/microsoft/frontend-bootcamp.git
synced 2026-01-26 14:56:42 +08:00
Merge branch 'master' of github.com:Microsoft/frontend-bootcamp
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## HTML Demo
|
||||
|
||||
The [HTML demo page](http://localhost:8080/step1-01/html-demo/html-demo.html) is 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).
|
||||
The [HTML demo page](https://microsoft.github.io/frontend-bootcamp/step1-01/html-demo/html-demo.html) is 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).
|
||||
|
||||
To learn more about each element, click on the element names below.
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ In this exercise we will scaffold out some HTML for our Todo app, then add some
|
||||
```
|
||||
|
||||
1. The DOCTYPE tells the browser that this file is written in modern HTML.
|
||||
2. The HTML tag wraps the entire page, and is the page root. Nothing is placed outside of those tags. Attributes can be set on HTML
|
||||
3. Head will contain all of the page's meta data, in this case a link to our CSS file
|
||||
2. The HTML tag wraps the entire page, and is the page root. Nothing is placed outside of those tags. Attributes can be set on HTML.
|
||||
3. Head will contain all of the page's meta data, in this case a link to our CSS file.
|
||||
4. Body is where all of the visible content should be placed.
|
||||
|
||||
### Content Sectioning
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# JavaScript Demo
|
||||
|
||||
Now that we a UI that looks like a todo app, we need to add functionality to make it **function** like a todo app. In this example we are going to use raw JavaScript explicitly modify our application as we interact with it. This will be in stark contrast to the implicit approach we will take when we do this with React in the next exercise.
|
||||
Now that we a UI that looks like a todo app, we need to add functionality to make it **function** like a todo app. In this example we are going to use raw JavaScript to explicitly modify our application as we interact with it. This will be in stark contrast to the implicit approach we will take when we do this with React in the next exercise.
|
||||
|
||||
> Keep an eye on how often user actions directly modify the HTML on the page. You'll see this number drop to zero when we start using React.
|
||||
|
||||
@@ -11,19 +11,19 @@ This demo starts off with a few elements already in place. Let's walk through wh
|
||||
- **clearInput()** - This is a generic, reusable function that takes in a `selector` parameter, finds the first matching element, and sets the element's value to an empty string. This direct modification is called a side effect.
|
||||
- **getTodoText()** - This is a quick helper function that returns the value inside of our textfield. Notice how some functions return values and how you can set that return to a variable.
|
||||
- **filter()** - This function takes in a `filterName` string, and a `button` which is a reference to the clicked button.
|
||||
1. Remove any `selected` class names
|
||||
2. Add `selected` to the clicked button
|
||||
1. Remove any `selected` class names.
|
||||
2. Add `selected` to the clicked button.
|
||||
3. Set `filterName` to the clicked button's `innerText` value.
|
||||
4. Get all of the todos with [querySelectAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll), and then loop through them.
|
||||
5. Set the `hidden` property of each todo based on the filter/state combination
|
||||
5. Set the `hidden` property of each todo based on the filter/state combination.
|
||||
|
||||
### Writing addTodo Function
|
||||
|
||||
1. `todo` is set to equal the first todo item
|
||||
2. `newTodo` is a clone of todo. Passing true means it is a deep clone, so we get the todo's children as well. Cloning does not duplicate the DOM node. We'll need to insert it in step 4
|
||||
> Note that this approach is very fragile, as it requires a todo node to always be present on the page
|
||||
3. We set the innerText of the `<span class='title'>` to the value returned from getTodoText
|
||||
> Note that if we left off the `()` we'd actually be assigning innerText to the 'function' instead of the function return
|
||||
1. `todo` is set to equal the first todo item.
|
||||
2. `newTodo` is a clone of todo. Passing true means it is a deep clone, so we get the todo's children as well. Cloning does not duplicate the DOM node. We'll need to insert it in step 4.
|
||||
> Note that this approach is very fragile, as it requires a todo node to always be present on the page.
|
||||
3. We set the innerText of the `<span class='title'>` to the value returned from getTodoText.
|
||||
> Note that if we left off the `()` we'd actually be assigning innerText to the 'function' instead of the function return.
|
||||
4. Insert our new todo into the todo's parent (the `ul`), before our reference todo. [insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore)
|
||||
|
||||
### Triggering functions from click events
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
|
||||
### Update Navigation
|
||||
|
||||
1. Add an onclick attribute to all 3 buttons in the navigation
|
||||
1. Add an onclick attribute to all 3 buttons in the navigation.
|
||||
2. For each onclick call the `filter` function. In our function we need a reference to the clicked button, so pass in the keyword `this` as the only parameter.
|
||||
|
||||
### Write updateRemaining function
|
||||
|
||||
1. Get a reference to the span with the `remaining` class, and store it in a variable
|
||||
1. Get a reference to the span with the `remaining` class, and store it in a variable.
|
||||
2. Use [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) to get all of the todos.
|
||||
3. Set the `innerText` of the remaining span to the length of those todos.
|
||||
4. Add updateRemaining() to end of addTodo function
|
||||
4. Add updateRemaining() to end of addTodo function.
|
||||
|
||||
### Write a clearCompleted function
|
||||
|
||||
1. Get a reference to all of the todos with [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)
|
||||
2. Use a `for (let todo of todos)` loop to iterate over each todo
|
||||
3. Inside the for loop write an `if` statement to test if the `input` inside of the todo has a checked value of true
|
||||
> Hint: you can use querySelector on any HTML node to find child elements within
|
||||
4. Call `todo.remove()` for any todo whos input check is true
|
||||
5. After the loop is done, run `updateRemaining()`
|
||||
6. Attach this function to the footer button
|
||||
1. Get a reference to all of the todos with [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll).
|
||||
2. Use a `for (let todo of todos)` loop to iterate over each todo.
|
||||
3. Inside the for loop write an `if` statement to test if the `input` inside of the todo has a checked value of true.
|
||||
> Hint: you can use querySelector on any HTML node to find child elements within.
|
||||
4. Call `todo.remove()` for any todo whos input check is true.
|
||||
5. After the loop is done, run `updateRemaining()`.
|
||||
6. Attach this function to the footer button.
|
||||
7. Test it out!
|
||||
|
||||
@@ -27,9 +27,9 @@ export class App extends React.Component {
|
||||
```
|
||||
|
||||
- **import React from 'react';** - This is how we [import modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) in JavaScript. This line creates a variable in this file called `React` that is equal to the default `export` of the `react` npm module.
|
||||
- **export class App** - Just like react exports code, our App component is nothing more than an exported "App" class. This allows us to import the class into other files
|
||||
- **export class App** - Just like react exports code, our App component is nothing more than an exported "App" class. This allows us to import the class into other files.
|
||||
- **extends React.Component** - A JavaScript class is similar to other programming languages (it's a collection of methods and properties). Classes can also be extended, so when we create a React component class, we always extend the base React.Component class. Note that this `Component` class is coming from the `React` variable imported up top.
|
||||
> Note that `<any, any>` is necessary for TypeScript which we will touch on later
|
||||
> Note that `<any, any>` is necessary for TypeScript which we will touch on later.
|
||||
- **render()** - One of the methods defined by React.Component is the `render()` method. This is a function that defines the HTML the component is going to render.
|
||||
- **return** - Remember that functions can return values in addition to side effects, and this component is no different.
|
||||
- **Inside of the return?** It's HTML! Actually, it's JSX, but with very few exceptions you can treat it like HTML. A few key differences:
|
||||
@@ -92,7 +92,7 @@ let pig = this.props.pig;
|
||||
let cow = this.props.cow;
|
||||
```
|
||||
|
||||
> Note that we access props and state on `this`, which is how you reference all of the class properties and methods
|
||||
> Note that we access props and state on `this`, which is how you reference all of the class properties and methods.
|
||||
|
||||
But this is verbose and repetitive. Instead you can use destructuring to turn this into a one liner.
|
||||
|
||||
@@ -122,7 +122,7 @@ Each JSX return needs to be a single element, so start with a wrapping `<div>`.
|
||||
|
||||
#### Updating the App to use Counters
|
||||
|
||||
Before we can use our `Counter`, we need to import it into the App file
|
||||
Before we can use our `Counter`, we need to import it into the App file.
|
||||
|
||||
```js
|
||||
import { Counter } from './components/Counter';
|
||||
@@ -169,7 +169,7 @@ Our next step is to wire up the button to increment the `counter` in our compone
|
||||
> By convention we place methods below render, and private methods (those for internal use only) are prefixed with an underscore.
|
||||
|
||||
```jsx
|
||||
_onButtonCLick = () => {
|
||||
_onButtonClick = () => {
|
||||
this.setState(prevState => ({ counter: prevState.counter + 1 }));
|
||||
};
|
||||
```
|
||||
@@ -183,7 +183,7 @@ This function will update our component state, incrementing our counter value by
|
||||
Now that we have a function to increment out count, all that we have left is to connect it to our button.
|
||||
|
||||
```jsx
|
||||
<button onClick={this._onButtonCLick}>Click</button>
|
||||
<button onClick={this._onButtonClick}>Click</button>
|
||||
```
|
||||
|
||||
> Note the syntax is a bit different than HTML. `onclick="funcName()"` vs `onClick={this.funcName}`
|
||||
@@ -207,8 +207,8 @@ export const Button = props => {
|
||||
};
|
||||
```
|
||||
|
||||
- All controls need to import React (don't worry, only 1 copy ever gets into your app)
|
||||
- Importing CSS files into the component means that the CSS is only loaded if the component is used
|
||||
- All controls need to import React (don't worry, only 1 copy ever gets into your app).
|
||||
- Importing CSS files into the component means that the CSS is only loaded if the component is used.
|
||||
- React components can be created as a class **or** as a function. In this function, props are passed in as a function parameter.
|
||||
> Until recently, you could only access state in class based components. But with the advent of [hooks](https://reactjs.org/docs/hooks-intro.html) you can create stateful function components.
|
||||
- Since this is a function, we don't have any methods, including `render()`. Just return your JSX as you would in a class based component.
|
||||
|
||||
Reference in New Issue
Block a user