分析demo.
-
组件分析
子组件父组件的关系
选择类组件还是函数组件?
依据:是否有状态。有:类组件(容器组件);没有:函数组件(UI)
-
数据位置:
条件:数据是某个组件自己用的话,那就定义在自己的组件中
条件:数据是多个组件共同用=>自定义在多个组件的共同的父组件中。
-
行为位置:
视图 - 行为 - 渲染
-
开发
定义组件 定义数据 定义行为 组件通信
开始:
定义组件:总父组件,以及三个子组件,分别为:输入组件,内容组件,item组件。
确定是类组件还是函数组件。
由于输入组件中,需要获取到输入的value值,且value值状态总会改变,所以用类。
其余两个只是用来做内容的UI,所以用函数组件。
定义好模板:
class AddTask extends React.Component {
state={task:""}
render(){
return(
<div>
<input type="text" />
<button >Add</button>
</div>
)
}
}
function TaskItems(){<ul><TaskItem/></ul>}
function TaskItem(){ return(
<li>
<span>1----aa---12.34</span>
<button>delete</button>
</li>)
}
class App extends React.Component{
state={tasks:[]}
render() {
return (
<div>
<h1>MY TASK:1</h1>
<AddTask />
<TaskItems />
</div>
)
}
}
初始UI已经搭建好,全部为静态数据。
下面慢慢分析:
在task中存放的数据为input输入的数据,所以要监听input的改变事件
handleChange = (e) => {
this.setState({
task: e.target.value
})
}
<input type="text" onChange={this.handleChange} />
当改变时获取到e.target.value,并把它同步更新到state中。
获得到input输入的值后,考虑如何将该task放入tasks中,从而渲染到items中呢?
首先书写点击事件:
handleClick = () => {
const { addTask } = this.props
const { task } = this.state
if (!task) return
let taskNew = { task: task, date: new Date().toLocaleTimeString() }
addTask(taskNew)
this.setState({
task:''
})
}
<button onClick={this.handleClick}>Add</button>
前提条件,task不为空,才可以被增加到tasks中哦。
已知tasks为数组,且在task中有索引、内容、日期,所以tasks中的每一个task都为一个对象。
将该对象获取到通过函数添加到tasks中。
---注意:因为此处要操作tasks,所以要写在App中。---
addTask=(task)=>{
const {tasks} = this.state
tasks.unshift(task)
this.setState({tasks})
}
因为在AddTask组件中调用了App组件中的函数,所以要通过props传递过去。
class App extends React.Component{
state={tasks:[]}
render() {
return (
<div>
<h1>MY TASK:1</h1>
<AddTask />
<TaskItems addTask={this.addTask} />//新增在这里
</div>
)
}
}
至此,完成了新增的操作,成功unshift在数组前成功显示了。
下面完成显示内容的操作。
App中在taskItems组件中传入整个tasks数组;
<TaskItems tasks={this.state.tasks} />
并在该组件接收,然后在TaskItems传递给子组件TaskItem:(task中有几个键值对哦)
const {tasks} = props
function TaskItems(){<ul>
{
tasks.map((item, index) => {
return <TaskItem index={index} item={item} key={index} />
})
}
</ul>}
成功传值,现在可以使用task中的数据啦~
function TaskItem(props) {
const { index, item } = props
const { task, date } = item
return <li>
<span>{index}---{task} ---{date}</span>
<button >delete</button>
</li>
}
至此,已成功完成新增数据的显示。
还有一个删除的操作。
还是那句话,tasks数据在App中,所以将删除函数写在APP组件中,就近原则吧。写完传给TaskItem组件
class App extends React.Component{
state={tasks:[]}
deleteTask=()=>{}
render() {
return (
<div>
<h1>MY TASK:1</h1>
<AddTask />
<TaskItems deleteTask={this.deleteTask} />
</div>
)
}
}
TaskItems还要通过props来传递给TaskItem....此处不粘贴代码,心累。
先分析删除的操作吧。
首先要获取到这个task的index,然后把index传给delete函数,通过splice的方法从index位置开始删除1个,也就是删除他自己。然后重新setState以下tasks就可以了。
- 传给方法一个index
function TaskItem(props) {
const { deleteTask } = props //从父组件中接收
const { task, date } = item
return <li>
<span>{index}---{task} ---{date}</span>
<button onClick={() => {
deleteTask(index) //接收到就可以调用了
}}>delete</button>
</li>
}
- 调用删除方法
deleteTask = (index) => {
const { tasks } = this.state
tasks.splice(index, 1)
this.setState({
tasks
})
}
至此,完成删除操作。
这个小demo真是用尽了我今天的精力,将之前的所有知识整合在了一起成为一个小练习,果然,有点绕弯弯在的。明天再自己做一遍试试看。