Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

基礎 Todo List #46

Open
futianshen opened this issue Dec 20, 2018 · 1 comment
Open

基礎 Todo List #46

futianshen opened this issue Dec 20, 2018 · 1 comment
Labels

Comments

@futianshen
Copy link
Collaborator

futianshen commented Dec 20, 2018

功能:新增、刪除清單內容
網址連結:待補

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import Todo from './Todo' 

class App extends React.Component { 
  constructor (props) {
    super(props) 
    this.state = { 
      value: '',
      todos: [],
      id: 0
    }
    this.handleClick = this.handleClick.bind(this)  // [1-2]
    this.handleChange = this.handleChange.bind(this)
    this.removeTodo = this.removeTodo.bind(this) 
    this.id = 0 
  }

  handleClick () {
    console.log(this) // [1-1]
    const { todos, value } = this.state
    this.setState({ 
      todos: [
        ...todos, 
        { 
          text: value,
          id: this.id++
        }
      ],
      value: ''
    })
  }

  handleChange (e) { 
    this.setState({
      value: e.target.value
    })
  }
  
  removeTodo (todo) {
    const { todos } = this.state
    this.setState({
      todos: todos.filter(item => item.id !== todo.id )
    })
  }
  render () {
    console.log('App Render!')
    const { todos, value } = this.state
    return (
      <div>
        <h1>Todo list React Version</h1>
        <label>todo: 
          <input value={value} onChange={this.handleChange} />
        </label>
        <button onClick={this.handleClick}>Add Todo</button> 
        <ul className="todolist">
          {todos.map(todo => <Todo 
            key={todo.id} 
            todo={todo} 
            removeTodo={this.removeTodo} 
          />)} 
        </ul>
      </div>
    )
  }
} 

ReactDOM.render(
  <App />, 
  document.getElementById('root')
)

Todo.js

import React from 'react'

class Todo extends React.Component {
  constructor(props) {
    super(props)
    this.handleDelete = this.handleDelete.bind(this)
  }
  shouldComponentUpdate(nextProps) {
    if(nextProps.todo===this.props.todo) return false
    else return true
  }
  handleDelete() {
    const { todo, removeTodo } = this.props
    removeTodo(todo)
  }
  render () {
    console.log('Todo Render')
    const { todo } = this.props
    return (
     <li>{todo.id}: {todo.text}
      <button onClick={this.handleDelete}>X</button>
    </li>
    )
  }
}

export default Todo
@futianshen
Copy link
Collaborator Author

futianshen commented Dec 20, 2018

[1] this 的指向 (理解錯誤需要修改)

一旦你瞭解物件你就可以瞭解 JavaScript,JavaScript 中幾乎所有事物都是一種「物件」,或具有類似物件的行為。[a]

this 指向調用 this 的物件 [b]

所有函式都由一個「物件」呼叫,換句話說所有函式都是物件中的一個「方法」(method) [c]

[1-1] handleClick 由 windows 物件(Global Object)呼叫, this 指向 windows 物件,但由於 babel 預設開啟 Strict Mode 所以變成 undefined

[1-2] 我們希望呼叫 handleClick 這個 method 的時候,this 的指向是 App 這個 Component 的Instance,但我們自訂的method handleClick() 指向的是 Global Object
所以我們我們利用 this.handleClick = this.handleClick.bind(this)

參考資料

[a]《JavaScript深入精要》p.1
[b]《從 ES6 開始的 JavaScript 學習生活》 this - this
[c]《從 ES6 開始的 JavaScript 學習生活》 this - 深入 函式 中

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant