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. 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. > Note that the function param and prop name just happen to be the same. This isn't required.
TodoListItemProps, extend, id, complete (possible abstraction) ## Exercise
add props, add complete to List item
## 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 1. Open TodoHeader and write TodoHeaderProps which will include 3 values. Replace the first `any` with this interface.
Add onClick to button 2. This component also has state. Write TodoHeaderState (there's just one item), and add this where the second `any` was.
Add types to header 3. Add `_onFilter` to each of the filter buttons
Add setFilter to filter buttons > Note that we can't add new parameters to onClick, but we can pull information from the event target!
write onAdd function 4. Write an `_onAdd` method that calls `addTodo` on the current `labelInput`, then sets the `labelInput` in state to an empty string
place onAdd to submit button 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> <button className="submit">Add</button>
</div> </div>
<nav className="filter"> <nav className="filter">
<button className={filter == 'all' ? 'completed' : ''}>all</button> <button className={filter == 'all' ? 'selected' : ''}>all</button>
<button className={filter == 'active' ? 'completed' : ''}>active</button> <button className={filter == 'active' ? 'selected' : ''}>active</button>
<button className={filter == 'completed' ? 'completed' : ''}>completed</button> <button className={filter == 'completed' ? 'selected' : ''}>completed</button>
</nav> </nav>
</header> </header>
); );

View File

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

View File

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

View File

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