app.js
//元件形式 function 函數形式 class類
// 01 react事件
import React, { Component } from 'react';
// 匯入react和react元件
// import ChildA from './components/ChildA'
// import ChildB from './components/ChilB'
// import Life from './components/Life'
import Todo from './pages/todo/index'
//定義一個App元件 繼承Component
class App extends Component {
//建構函式
constructor(props) {
super(props);
//呼叫父元件
this.state = { num: 1 }
//定義一個狀態 (data資料)
}
//渲染節點
render() {
return (
<div >
<Todo></Todo>
</div>
);
}
}
export default App;
index.js
import React, { Component } from 'react'
import List from './List';
import Input from './Input'
class Todo extends Component {
constructor(props) {
super(props);
this.state = {
list:[
{done:false,title:"學習react",status:0},
{done:true,title:"學習vue",status:0},
{done:false,title:"小程式",status:0}
]
}
}
// 新增item
addItem = e=>{
var list = this.state.list; //獲取到原list
list.unshift({title:e.title,done:false,status:0}) //把新資料新增到list
this.setState({list}) //更新list
}
// 刪除item
delItem = item=>{
var list = this.state.list;
var ind = list.indexOf(item);
list.splice(ind,1);
this.setState({list})
}
// item被改變
itemChange = (item,data)=>{
var list = this.state.list; //獲取原來的list
var ind = list.indexOf(item); //獲取是第幾個
list[ind]={...item,...data} //用data 去覆蓋item的屬性
this.setState({list}) //更新list
}
render() {
let listUndo = this.state.list.filter(item=>!item.done); //未完成
let listDone = this.state.list.filter(item=>item.done); //已經完成
return (
<div>
<h1>TodoList</h1>
<Input addItem={this.addItem}></Input>
{/* addItem方法通過props addItem傳入給Input */}
<h3>未完成({listUndo.length})</h3>
<List
list={listUndo}
delItem={this.delItem}
itemChange={this.itemChange}
></List>
<h3>已經完成({ listDone.length})</h3>
<List
list={listDone}
delItem={this.delItem}
itemChange={this.itemChange}
></List>
</div> );
}
}
export default Todo;
List.js
import React from 'react'
import Item from './Item.js'
function List({list,delItem,itemChange}){
return (
<div className="list">
{
list.map(
item=>{
return (
<Item
key={item.title}
item={item}
delItem={delItem}
itemChange={itemChange}>
</Item>
)}
)
// 把list通過map對映為有Item元件的陣列 並傳入item資料給Item元件
}
</div>)
}
export default List;
Item.js
import React, { Component } from 'react'
class Item extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
let {item,delItem,itemChange} = this.props
// 簡寫props.item
return (
<div>
<span>
<input type="checkbox" checked={item.done} onChange={e=>itemChange(item,{done:e.target.checked})}/>
<span>{item.title}</span>
<button onClick={()=>{delItem(item)}}>×</button>
</span>
</div> );
}
}
export default Item;
Input.js
import React from 'react';
function Input({addItem}){
let inp = null; //定義inp 通過ref函數獲取到 input節點
return (<div>
<input
type="text"
placeholder="新增內容"
ref={elem=>inp=elem}
onKeyUp={e=>{
if(e.keyCode!==13){return}
addItem({title:inp.value,status:0})
inp.value = "";
}}
/>
<button onClick={()=>{
// 當單擊新增按鈕是 執行props 的addItem方法
addItem({title:inp.value,status:0});
inp.value = "";
}}>新增</button>
</div>)
}
export default Input;