finished step 7 docs

This commit is contained in:
Micah Godbolt
2019-02-23 21:12:23 -08:00
parent 710064c355
commit c11233bafa
5 changed files with 47 additions and 22 deletions

View File

@@ -160,20 +160,29 @@ const { label, completed, complete, id } = this.props;
And then use the input's `onChange` event to fire our `complete` callback. We can see in the signature that we expect and `id` of type string, so we'll pass our `id` prop in.
```tsx
<input type="checkbox" checked={completed} onChange={() => complete(id)} />
```
> Note that the function param and prop name just happen to be the same. This isn't required.
TodoListItemProps, extend, id, complete (possible abstraction)
add props, add complete to List item
## Exercise
## List
### TodoFooter
Demo how you can't add random things to TodoListItem or item's this.props now
1. Open TodoFooter and write a TodoFooterProps interface. It should include two values, a function and an object. Assign this interface to props like this: `(props: TodoFooterProps)`
2. Write an `_onClick` function that calls `props.clear`.
> Since TodoFooter is not a class the `_onClick` needs to be declared as a const, and placed before the `return`.
3. Add `_onClick` to the button's `onClick`. You won't need to use `this` since this isn't a class.
> We can't assign our `clear` function directly to `onClick`. We always need to create a function that calls our callbacks. `() => props.clear()`
4. Test out this functionality. Check a few todos complete and click the `Clear Completed` button
exercise
### TodoHeader
Add types to footer
Add onClick to button
Add types to header
Add setFilter to filter buttons
write onAdd function
place onAdd to submit button
1. Open TodoHeader and write TodoHeaderProps which will include 3 values. Replace the first `any` with this interface.
2. This component also has state. Write TodoHeaderState (there's just one item), 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
5. Call `_onAdd` from the submit button
6. Check out this new functionality! We can now add and filter todos!

View File

@@ -17,9 +17,9 @@ export class TodoHeader extends React.Component<any, any> {
<button className="submit">Add</button>
</div>
<nav className="filter">
<button className={filter == 'all' ? 'completed' : ''}>all</button>
<button className={filter == 'active' ? 'completed' : ''}>active</button>
<button className={filter == 'completed' ? 'completed' : ''}>completed</button>
<button className={filter == 'all' ? 'selected' : ''}>all</button>
<button className={filter == 'active' ? 'selected' : ''}>active</button>
<button className={filter == 'completed' ? 'selected' : ''}>completed</button>
</nav>
</header>
);

View File

@@ -17,14 +17,18 @@ export class TodoHeader extends React.Component<any, any> {
<button className="submit">Add</button>
</div>
<nav className="filter">
<button className={filter == 'all' ? 'completed' : ''}>all</button>
<button className={filter == 'active' ? 'completed' : ''}>active</button>
<button className={filter == 'completed' ? 'completed' : ''}>completed</button>
<button className={filter == 'all' ? 'selected' : ''}>all</button>
<button className={filter == 'active' ? 'selected' : ''}>active</button>
<button className={filter == 'completed' ? 'selected' : ''}>completed</button>
</nav>
</header>
);
}
_onFilter = evt => {
this.props.setFilter(evt.target.textContet);
};
_onChange = evt => {
this.setState({ labelInput: evt.target.value });
};

View File

@@ -7,12 +7,16 @@ interface TodoFooterProps {
export const TodoFooter = (props: TodoFooterProps) => {
const itemCount = Object.keys(props.todos).filter(id => !props.todos[id].completed).length;
const _onClick = () => {
props.clear();
};
return (
<footer>
<span>
{itemCount} item{itemCount > 1 ? 's' : ''} left
</span>
<button onClick={() => props.clear()} className="submit">
<button onClick={_onClick} className="submit">
Clear Completed
</button>
</footer>

View File

@@ -7,7 +7,11 @@ interface TodoHeaderProps {
filter: FilterTypes;
}
export class TodoHeader extends React.Component<TodoHeaderProps, any> {
interface TodoHeaderState {
labelInput: string;
}
export class TodoHeader extends React.Component<TodoHeaderProps, TodoHeaderState> {
constructor(props) {
super(props);
this.state = { labelInput: '' };
@@ -25,13 +29,13 @@ export class TodoHeader extends React.Component<TodoHeaderProps, any> {
</button>
</div>
<nav className="filter">
<button onClick={() => setFilter('all')} className={filter == 'all' ? 'completed' : ''}>
<button onClick={this._onFilter} className={filter == 'all' ? 'selected' : ''}>
all
</button>
<button onClick={() => setFilter('active')} className={filter == 'active' ? 'completed' : ''}>
<button onClick={this._onFilter} className={filter == 'active' ? 'selected' : ''}>
active
</button>
<button onClick={() => setFilter('completed')} className={filter == 'completed' ? 'completed' : ''}>
<button onClick={this._onFilter} className={filter == 'completed' ? 'selected' : ''}>
completed
</button>
</nav>
@@ -39,6 +43,10 @@ export class TodoHeader extends React.Component<TodoHeaderProps, any> {
);
}
_onFilter = evt => {
this.props.setFilter(evt.target.textContet);
};
_onChange = evt => {
this.setState({ labelInput: evt.target.value });
};