React技巧6(TodoList实现2组件之间传递数据)

React技巧6(TodoList实现2组件之间传递数据)

React技巧6(TodoList实现2组件之间传递数据)

本教程总共5篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章!


1.React 技巧1(状态组件与无状态组件的使用) ----2018.01.04


2.React 技巧2(避免无意义的父节点)----2018.01.05


3.React 技巧3(如何优雅的渲染一个List)----2018.01.06


4.React 技巧4(如何处理List里面的Item)----2018.01.07


5.React 技巧5(TodoList实现)----2018.01.08


6.React技巧6(TodoList实现2组件之间传递数据)---2018.01.09(新增)


7.React技巧7(TodoList实现3组件之间传递数据之优化)---2018.01.10(新增)


开发环境:Windows 8,node v8.9.1,npm 5.5.1,WebStorm 2017.2.2


我们看下上节课程 React技巧5(TodoList实现),我们改造下工程,复制出来一份,为demo2

React技巧6(TodoList实现2组件之间传递数据)

因为是新的页面,我们在 config -> entry -> entry.js 里新增一个json对象,demo2

React技巧6(TodoList实现2组件之间传递数据)

然后 

npm run devNew

npm run dev

看下浏览器

React技巧6(TodoList实现2组件之间传递数据)

OK 正常,

我们这节课在这个demo2讲解!


假设我们要实现这样的需求:

1、显示三块内容,全部、未删除、已删除

2、未删除后面有删除按钮

3、已删除后面恢复按钮

最后的效果如下:

React技巧6(TodoList实现2组件之间传递数据)

好,我们现在开始开发:

1、显示三块内容,全部、未删除、已删除

先把LIst抽出做成List组件

原来是这样:

React技巧6(TodoList实现2组件之间传递数据)

我们的设计原则是:尽量把增、删、改、查等逻辑方法及状态放在父组件中

List组件只作为展示组件,所有它页是无状态组件!

import React from 'react';

const List = ({list}) =>
<div className="list">
       {
list.map(data => [
data.status === 1 ?
<li key={data.id}>
                       {data.title}
<button onClick={() => this.handleItemDel(data.id)}>删除</button>
                   </li>
                   :
null
           ])
}
</div>
;

export default List;

React技巧6(TodoList实现2组件之间传递数据)

我们在父组件:TodoList中引入 List组件,并把 list状态,及删除方法传递给List组件

这里面增加了这几句代码:

import List from './List';
this.handleItemDel = this.handleItemDel.bind(this)
<List list={list} handleItemDel={this.handleItemDel}/>

React技巧6(TodoList实现2组件之间传递数据)

相应的页需要改造下List组件代码:

import React from 'react';

const List = ({list,handleItemDel}) =>
<div className="list">
       {
list.map(data => [
data.status === 1 ?
<li key={data.id}>
                       {data.title}
<button onClick={() => handleItemDel(data.id)}>删除</button>
                   </li>
                   :
null
           ])
}
</div>
;

export default List;

React技巧6(TodoList实现2组件之间传递数据)

这就是父组件给子组件,传递状态及方法的示列!

子组件接收到父组件状态,进行渲染。用户点击删除,子组件调用父组件删除方法,进行删除。

我们来把三块内容写出来:

React技巧6(TodoList实现2组件之间传递数据)

这里下需要修改下 todoList.pcss

.todoList {
.box{
float: left;
   width: 300px;
 }
li {
list-style-type: none;
   margin-top: 10px;
 }
button {
border: 1px solid #cccccc;
   border-radius: 4px;
   font-size: 12px;
   padding: 2px 10px;
   margin-left: 10px;
 }
}

React技巧6(TodoList实现2组件之间传递数据)

现在三块内容显示的都是一样的,我们来区分一下,那么我们就要给子组件转递一个标识,告诉子组件,当前应该渲染那一部分内容!

我们设定传一个type 给子组件,并且规定 0 是全部 、1是未删除、2是已删除

<div className="cont">
   <div className="box">
       全部
<List list={list} handleItemDel={this.handleItemDel} type={0}/>
   </div>
   <div className="box">
       未删除
<List list={list} handleItemDel={this.handleItemDel} type={1}/>
   </div>
   <div className="box">
       已删除
<List list={list} handleItemDel={this.handleItemDel} type={2}/>
   </div>
</div>

React技巧6(TodoList实现2组件之间传递数据)

然后我们修改下,List组件:

{
list.map(data => [
type === 0 ?
<li key={data.id}>
               {data.title}
<button onClick={() => handleItemDel(data.id)}>删除</button>
           </li>
           :
type === 1 && data.status === 1 ?
<li key={data.id}>
                   {data.title}
<button onClick={() => handleItemDel(data.id)}>删除</button>
               </li>
               :
type === 2 && data.status === 0 ?
<li key={data.id}>
                       {data.title}
<button onClick={() => handleItemDel(data.id)}>删除</button>
                   </li>
                   :
null
   ])
}

React技巧6(TodoList实现2组件之间传递数据)

看下浏览器

React技巧6(TodoList实现2组件之间传递数据)

2、未删除后面有删除按钮

3、已删除后面恢复按钮

这两个需求我们一起来实现

首先,未删除的现在有删除按钮,我们先把已删除那块内容,按钮变成恢复按钮,并写上逻辑

修改 TodoList.jsx

this.handleItemRecovery = this.handleItemRecovery.bind(this)
handleItemRecovery(id) {
let list = this.state.list;
   list.find(data => data.id === id).status = 1;
   this.setState({list: list})
}
<div className="box">
   已删除
<List list={list} handleItemRecovery={this.handleItemRecovery} type={2}/>
</div>

React技巧6(TodoList实现2组件之间传递数据)

React技巧6(TodoList实现2组件之间传递数据)

看下浏览器

React技巧6(TodoList实现2组件之间传递数据)

目前已经可以恢复了!

我们还得修改下,全部这一块的按钮,

为了直观一点,我们加上样式!

.todoList {
.box{
float: left;
   width: 300px;
 }
li {
list-style-type: none;
   margin-top: 10px;
 }
button {
border: none;
   border-radius: 4px;
   font-size: 12px;
   padding: 2px 10px;
   margin-left: 10px;
 }
.del{
background-color: #f00000;
   color: #FFFFFF;
 }
.recovery{
background-color: chartreuse;
 }
}

修改下TodoList.jsx

React技巧6(TodoList实现2组件之间传递数据)

修改下List 组件

React技巧6(TodoList实现2组件之间传递数据)

{
data.status === 1 ?
<button onClick={() => handleItemDel(data.id)} className="del">删除</button>
       :
<button onClick={() => handleItemRecovery(data.id)} className="recovery">恢复</button>
}

以上两个组件完整代码如下:

TodoList.jsx

import React from 'react';
import List from './List';
import '../../../public/css/todoList.pcss';

class TodoList extends React.Component {
constructor(props) {
super(props);
       this.state = {
list: []
};
       this.handleAdd = this.handleAdd.bind(this);
       this.handleItemDel = this.handleItemDel.bind(this);
       this.handleItemRecovery = this.handleItemRecovery.bind(this)
}

handleAdd() {
let item = this.refs['todoInput'].value;
       if (item) {
let list = this.state.list;
           list.push({id: list.length + 1, title: item, status: 1});
           this.setState({list: list}, () => console.log(this.state.list))
} else {
alert('不能为空')
}
}

handleItemDel(id) {
let list = this.state.list;
       list.find(data => data.id === id).status = 0;
       this.setState({list: list})
}

handleItemRecovery(id) {
let list = this.state.list;
       list.find(data => data.id === id).status = 1;
       this.setState({list: list})
}

componentDidMount() {

}

render() {
let {list} = this.state;
       return (
<div className="todoList">
               <input type="text" ref="todoInput"/>
               <button onClick={this.handleAdd}>添加</button>
               <div className="cont">
                   <div className="box">
                       全部
<List list={list} handleItemDel={this.handleItemDel} handleItemRecovery={this.handleItemRecovery} type={0}/>
                   </div>
                   <div className="box">
                       未删除
<List list={list} handleItemDel={this.handleItemDel} type={1}/>
                   </div>
                   <div className="box">
                       已删除
<List list={list} handleItemRecovery={this.handleItemRecovery} type={2}/>
                   </div>
               </div>
           </div>
       );
   }
}

export default TodoList;

List.jsx

import React from 'react';

const List = ({list, handleItemDel, type, handleItemRecovery}) =>
<div className="list">
       {
list.map(data => [
type === 0 ?
<li key={data.id}>
                       {data.title}
{
data.status === 1 ?
<button onClick={() => handleItemDel(data.id)} className="del">删除</button>
                               :
<button onClick={() => handleItemRecovery(data.id)} className="recovery">恢复</button>
                       }
</li>
                   :
type === 1 && data.status === 1 ?
<li key={data.id}>
                           {data.title}
<button onClick={() => handleItemDel(data.id)} className="del">删除</button>
                       </li>
                       :
type === 2 && data.status === 0 ?
<li key={data.id}>
                               {data.title}
<button onClick={() => handleItemRecovery(data.id)} className="recovery">恢复</button>
                           </li>
                           :
null
           ])
}
</div>
;

export default List;

todoList.pcss

.todoList {
.box{
float: left;
   width: 300px;
 }
li {
list-style-type: none;
   margin-top: 10px;
 }
button {
border: none;
   border-radius: 4px;
   font-size: 12px;
   padding: 2px 10px;
   margin-left: 10px;
 }
.del{
background-color: #f00000;
   color: #FFFFFF;
 }
.recovery{
background-color: chartreuse;
 }
}

我们来看下浏览器效果。


React技巧6(TodoList实现2组件之间传递数据)

本文完 React技巧6(TodoList实现2组件之间传递数据)React技巧6(TodoList实现2组件之间传递数据)React技巧6(TodoList实现2组件之间传递数据)React技巧6(TodoList实现2组件之间传递数据)React技巧6(TodoList实现2组件之间传递数据)React技巧6(TodoList实现2组件之间传递数据)

React技巧6(TodoList实现2组件之间传递数据)

禁止擅自转载,如需转载请在公众号中留言联系我们!

感谢童鞋们支持!

如果你有什么问题,可以在下方留言给我们!