- Slide, then...
- Difference between props and state is change over time. If I were a React component, my name is a good property because that isn't likely to change. My level of thirst is good state, because that changes
- Slide, then...
- setState is passed an object with keys that you want to change. In this example, it would be incrementing this.state.counter by one. This component might have other pieces of state, but this call to setState doesn't affect them
- Deciding on your application's data model is crucial to building a good app. In this case, a todo item should be represented by an object with two keys: task, which is a description of the todo item, and done, which keeps track of whether the todo is completed
- Slide, then..
- We're going to keep the todos in one place, a single source of truth
- Slide then
- By keeping components small and isolated, they're easier to write, easier to understand, and easier to test
- Slide then
- This may look weird seeing an array of JSX here, but remember that Babel turns them into function calls
- Slide then
- React will render each of them as sibling elements
- Slide then
- With only one conditional class, string manipulation works. But it quickly gets messy with multiple classes.
- Slide then
- We're going to pass
addTodo
as a prop to TodoInput, but we're going to use the nameonSubmit
- this is because TodoInput shouldn't know about adding todos. We might want to use a TodoInput component later for a search input. TodoInput gets passed a function to call when a user submits the input, hence the nameonSubmit
.
- To figure out when we should fire
this.props.onSubmit
, we'll add anonKeyDown
handler in TodoInput - We'll listen for the ENTER key, which has a keycode of 13
- If the user has hit the ENTER key, then we call
this.props.onSubmit
with the current value, and then and clear it to leave an empty input ready for the next todo item
- Now we have to actually do something in
App.addTodo
- We create a new todo object with the task that was passed in from TodoInput
- Then we add the newTodo to the end of our current list - the ... is called the spread operator because it "spreads" its contents into an array. This will create a new array comprised of this.state.todos, with the newTodo added
- Finally, we setState to update our app
- We have to pass
toggleTodo
from App to TodoList, then from TodoList to every TodoItem - Just like when adding todos, we're going to use different names for the properties in each step - TodoList doesn't know about "toggling todos", it just wants a function to call when a todo gets clicked, so
onTodoClick
is a good name. Same with the TodoItems - they just want a function to call on click, soonClick
is a good name.
- Which TodoItem called App.toggleTodo? Every TodoItem calls exact same function in the same way, no way for App to know
- Need TodoItem to "tell" App which one was clicked
- Add argument to
toggleTodo()
, and have TodoItem pass that argument when calling
- Let's use position in the list to identify
- Can get that position from
index
in the TodoItems map function, just like we used for the key - Can't pass in
this.props.onTodoClick
directly - this would callthis.props.onTodoClick
and pass the result as a prop, but what we want is to pass the function itself
- Functions that "saves" some data for another time or place where we don't have access to it
- The name comes from the function "closing" over a variable
- In this example, we have a variable,
msg
, and a function,logMsg
that closes over it - If we passed
logMsg
to MyComponent, it will still console.log 'hey there' even though MyComponent doesn't have access to themsg
variable
- We're going to make a new function to pass into each TodoItem that calls
app.toggleTodo
- We use a fat arrow function because we want to make sure that
this
really points to the TodoList component - sometimes when you have event handlers,this
can end up pointing to the wrong thing - Now instead of calling
App.toggleTodo
directly when a user clicks on a TodoItem, it will call our new function with the proper index
05-toggle-todo
{markdownSlide("# Todone!\n\n### Where to go from here")}
{markdownSlide(require("raw!./slides/outro/01-summary
{markdownSlide(require("raw!./slides/outro/02-further-development
{markdownSlide(require("raw!./slides/outro/03-only-beginning
{markdownSlide(require("raw!./slides/outro/04-thanks