readme cleanup

This commit is contained in:
Micah Godbolt
2019-03-03 21:35:32 -08:00
parent a8f5965756
commit 6b69b0164c
33 changed files with 80 additions and 426 deletions

View File

@@ -120,35 +120,25 @@ Now that our interface is complete, try changing the word "all" in `filter === a
Most of our components will need to specify types for `todos` and `filter`, so it's a good thing that TypeScript allows us to share types between files. I've already written up and exported those shared types in the file `TodoApp.types.ts`, so we just need to import them and use them in our interface.
```ts
import { FilterTypes, Todos } from '../TodoApp.types';
import { FilterTypes, Todos, CompleteTodo } from '../TodoApp.types';
interface TodoListProps {
complete: (id: string) => void;
complete: CompleteTodo;
todos: Todos;
filter: FilterTypes;
}
```
## Updating TodoApp
Our `TodoApp` doesn't take any props, but it does have state. We can use TypeScript to define that as well.
I've already imported `Todos` and `FilterTypes` into the `TodoApp`, so we just need to add them to our class. If we want, we can even skip a separate interface definition and just declare the type inline. (This is not recommended for types of any complexity or types that are used in multiple places.)
```ts
export class TodoApp extends React.Component<{}, { todos: Todos; filter: FilterTypes }>
```
> Note that the first value in `<>` always refers to props. Since `TodoApp` takes none, we'll set it to an empty object type.
## Writing TodoListItemProps
Jumping down to the TodoListItem, as we start to write the `TodoListItemProps` we realize that two of the props, `label` and `completed`, have already been defined in the `TodoItem` interface in `TodoApp.types`. So we can make `TodoListItemProps` reuse the `TodoItem` interface by extending it.
Jumping down to the TodoListItem, as we start to write the `TodoListItemProps` we realize that two of the props, `label` and `completed`, have already been defined in the `TodoItem` interface. So we can make `TodoListItemProps` reuse the `TodoItem` interface by extending it.
```ts
import { CompleteTodo } from '../TodoApp.types';
interface TodoListItemProps extends TodoItem {
id: string;
complete: (id: string) => void;
complete: CompleteTodo;
}
```

View File

@@ -6,7 +6,12 @@ import { Todos, FilterTypes } from './TodoApp.types';
let index = 0;
export class TodoApp extends React.Component<any, any> {
interface TodoAppState {
todos: Todos;
filter: FilterTypes;
}
export class TodoApp extends React.Component<any, TodoAppState> {
constructor(props) {
super(props);
this.state = {

View File

@@ -1,5 +1,7 @@
export type FilterTypes = 'all' | 'active' | 'completed';
export type CompleteTodo = (id) => null;
export interface TodoItem {
label: string;
completed: boolean;

View File

@@ -6,6 +6,7 @@ export class TodoList extends React.Component<any, any> {
render() {
const { filter, todos, complete } = this.props;
// filteredTodos returns an array of filtered todo keys [01,02,03]
const filteredTodos = Object.keys(todos).filter(id => {
return filter === 'all' || (filter === 'completed' && todos[id].completed) || (filter === 'active' && !todos[id].completed);
});

View File

@@ -1,29 +1,27 @@
## Exercise
#Step 1-07: 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
### TodoFooter
1. Open TodoFooter and write a TodoFooterProps interface. It should include two values, a function and an object. 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`.
3. Assign `_onClick` to the button's `onClick` prop. You won't need to use `this` since the component isn't a class.
4. Test out this functionality. Check a few todos complete and click the `Clear Completed` button.
### TodoHeader
## TodoHeader
1. Open TodoHeader and write TodoHeaderProps which will include three values. 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.
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!
4. Write an `_onAdd` method that calls `addTodo` on the current `labelInput`, then sets the `labelInput` in state to an empty string
4. Call `_onAdd` from the submit button
5. Call `_onAdd` from the submit button
6. Check out this new functionality! We can now add and filter todos!
5. Check out this new functionality! We can now add and filter todos!

View File

@@ -1,5 +1,7 @@
export type FilterTypes = 'all' | 'active' | 'completed';
export type CompleteTodo = (id) => null;
export interface TodoItem {
label: string;
completed: boolean;

View File

@@ -32,4 +32,9 @@ export class TodoHeader extends React.Component<any, any> {
_onChange = evt => {
this.setState({ labelInput: evt.target.value });
};
_onAdd = () => {
this.props.addTodo(this.state.labelInput);
this.setState({ labelInput: '' });
};
}

View File

@@ -12,6 +12,7 @@ export class TodoList extends React.Component<TodoListProps, any> {
render() {
const { filter, todos, complete } = this.props;
// filteredTodos returns an array of filtered todo keys [01,02,03]
const filteredTodos = Object.keys(todos).filter(id => {
return filter === 'all' || (filter === 'completed' && todos[id].completed) || (filter === 'active' && !todos[id].completed);
});