diff --git a/step2-05/exercise/src/reducers/pureFunctions.spec.ts b/step2-05/exercise/src/reducers/pureFunctions.spec.ts index c8e202a..aa7018e 100644 --- a/step2-05/exercise/src/reducers/pureFunctions.spec.ts +++ b/step2-05/exercise/src/reducers/pureFunctions.spec.ts @@ -21,5 +21,5 @@ describe('TodoApp reducers', () => { */ }); - // TODO: test remove, complete and clear + // TODO: add a test for remove() }); diff --git a/step2-05/exercise/src/reducers/pureFunctions.ts b/step2-05/exercise/src/reducers/pureFunctions.ts index 12ca8ef..4f2b931 100644 --- a/step2-05/exercise/src/reducers/pureFunctions.ts +++ b/step2-05/exercise/src/reducers/pureFunctions.ts @@ -19,20 +19,21 @@ export function remove(state: Store['todos'], id: string) { } export function complete(state: Store['todos'], id: string) { - // Write code: - // - to clone the state[id] object into new todo object, using the spread syntax - // - in the spread syntax, also override the value of the completed key like this: {...foo, [id]: !foo[id].completed} - // - modify new state and set the id key to the value of the new item object - - return state; + // Clone the todo, overriding + const newTodo = { ...state[id], completed: !state[id].completed }; + return { ...state, [id]: newTodo }; } export function clear(state: Store['todos']) { - // Write code: - // - to clone the state object into new state object - // - loop through the keys of the new state object - // - remove those items inside that new state if the item is completed using the "delete" keyword - // - return the new state + // Clone the todos + const newTodos = { ...state }; - return state; + // Delete all todos based on the completed flag, looping over the keys of the todos + Object.keys(state).forEach(key => { + if (state[key].completed) { + delete newTodos[key]; + } + }); + + return newTodos; } diff --git a/step2-07/demo/README.md b/step2-07/demo/README.md index 3aeff02..61dce33 100644 --- a/step2-07/demo/README.md +++ b/step2-07/demo/README.md @@ -16,7 +16,7 @@ That's right, Redux doesn't just work with React. It can also be used with Vue.j The store doesn't magically get passed to the views. It has to be supplied by a `react-redux` component called [``](https://react-redux.js.org/api/provider). A `` can be placed anywhere, but it's best to just make it available at the root the app: -```tsx +```js const store = createStore(reducers); const App = () => { @@ -32,7 +32,7 @@ const App = () => { `react-redux` provides a [`connect()`](https://react-redux.js.org/api/connect) function that turns the Redux store and dispatch functions into props for React components. The state and action dispatchers are passed along with a `` component. -```ts +```js const OldComponent = props => { return
{props.foo}
; }; diff --git a/step2-07/demo/src/components/TodoFooter.tsx b/step2-07/demo/src/components/TodoFooter.tsx index abd4932..d876d41 100644 --- a/step2-07/demo/src/components/TodoFooter.tsx +++ b/step2-07/demo/src/components/TodoFooter.tsx @@ -10,7 +10,8 @@ interface TodoFooterProps { } const TodoFooter = (props: TodoFooterProps) => { - const itemCount = Object.keys(props.todos).filter(id => !props.todos[id].completed).length; + const { todos } = props; + const itemCount = todos ? Object.keys(todos).filter(id => !props.todos[id].completed).length : 0; return ( diff --git a/step2-07/exercise/README.md b/step2-07/exercise/README.md index 1f04e34..cc4b35f 100644 --- a/step2-07/exercise/README.md +++ b/step2-07/exercise/README.md @@ -4,6 +4,8 @@ If you still have `npm test` running from the last step, stop it using `ctrl+C`. Start the app by running `npm start` from the root of the `frontend-bootcamp` folder. Click the "exercise" link under day 2 step 7 to see results. +At the beginning of this exercise, the "Add" and "Clear Completed" buttons do not work. We'll be fixing that in this step! + 1. Open `exercise/src/index.tsx` and wrap `` with `` as instructed in the comment 2. Open `exercise/src/components/TodoFooter.tsx` and erase the "nullable" type modifier (i.e. the ?) in the interface definition of `TodoFooterProps` diff --git a/step2-07/exercise/src/components/TodoFooter.tsx b/step2-07/exercise/src/components/TodoFooter.tsx index 6c11cbc..b97194a 100644 --- a/step2-07/exercise/src/components/TodoFooter.tsx +++ b/step2-07/exercise/src/components/TodoFooter.tsx @@ -11,7 +11,8 @@ interface TodoFooterProps { } export const TodoFooter = (props: TodoFooterProps) => { - const itemCount = Object.keys(props.todos).filter(id => !props.todos[id].completed).length; + const { todos } = props; + const itemCount = todos ? Object.keys(todos).filter(id => !props.todos[id].completed).length : 0; return ( diff --git a/step2-07/exercise/src/index.tsx b/step2-07/exercise/src/index.tsx index 6c891b4..f14f51c 100644 --- a/step2-07/exercise/src/index.tsx +++ b/step2-07/exercise/src/index.tsx @@ -15,5 +15,10 @@ store.dispatch(actions.addTodo('world')); initializeIcons(); -// TODO: wrap with a instance here -ReactDOM.render(, document.getElementById('app')); +// TODO: see how we added Provider is the root element +ReactDOM.render( + + + , + document.getElementById('app') +); diff --git a/step2-08/demo/src/components/TodoFooter.tsx b/step2-08/demo/src/components/TodoFooter.tsx index 417c3e2..5805f34 100644 --- a/step2-08/demo/src/components/TodoFooter.tsx +++ b/step2-08/demo/src/components/TodoFooter.tsx @@ -10,7 +10,8 @@ interface TodoFooterProps { } const TodoFooter = (props: TodoFooterProps) => { - const itemCount = Object.keys(props.todos).filter(id => !props.todos[id].completed).length; + const { todos } = props; + const itemCount = todos ? Object.keys(todos).filter(id => !props.todos[id].completed).length : 0; return (