微信公眾號(hào)首發(fā)
本教程總共5篇,每日更新一篇,請(qǐng)關(guān)注我們!你可以進(jìn)入歷史消息查看以往文章,也敬請(qǐng)期待我們的新文章!
1.React 技巧1(狀態(tài)組件與無狀態(tài)組件的使用) ----2018.01.04
2.React 技巧2(避免無意義的父節(jié)點(diǎn))----2018.01.05
3.React 技巧3(如何優(yōu)雅的渲染一個(gè)List)----2018.01.06
4.React 技巧4(如何處理List里面的Item)----2018.01.07
5.React 技巧5(TodoList實(shí)現(xiàn))----2018.01.08
6.React技巧6(TodoList實(shí)現(xiàn)2組件之間傳遞數(shù)據(jù))---2018.01.09(新增)
7.React技巧7(TodoList實(shí)現(xiàn)3組件之間傳遞數(shù)據(jù)之優(yōu)化)---2018.01.10(新增)
開發(fā)環(huán)境:Windows 8,node v8.9.1,npm 5.5.1,WebStorm 2017.2.2
我們看下上節(jié)課程 React技巧5(TodoList實(shí)現(xiàn)),我們改造下工程,復(fù)制出來一份,為demo2
因?yàn)槭切碌捻撁妫覀冊(cè)?config -> entry -> entry.js?里新增一個(gè)json對(duì)象,demo2
然后?
npm?run?devNew
npm?run?dev
看下瀏覽器
OK?正常,
我們這節(jié)課在這個(gè)demo2講解!
假設(shè)我們要實(shí)現(xiàn)這樣的需求:
1、顯示三塊內(nèi)容,全部、未刪除、已刪除
2、未刪除后面有刪除按鈕
3、已刪除后面恢復(fù)按鈕
最后的效果如下:
好,我們現(xiàn)在開始開發(fā):
1、顯示三塊內(nèi)容,全部、未刪除、已刪除
先把LIst抽出做成List組件
原來是這樣:
我們的設(shè)計(jì)原則是:盡量把增、刪、改、查等邏輯方法及狀態(tài)放在父組件中
List組件只作為展示組件,所有它頁是無狀態(tài)組件!
import Reactfrom 'react';
const List = ({list}) =>
? ? ? ?{
list.map(data => [
data.status ===1 ?
? ? ? ? ? ? ? ? ? ? ? ?{data.title}
this.handleItemDel(data.id)}>刪除
? ? ? ? ? ? ? ? ? ?:
null
? ? ? ? ? ?])
}
;
export default List;
我們?cè)诟附M件:TodoList中引入 List組件,并把?list狀態(tài),及刪除方法傳遞給List組件
這里面增加了這幾句代碼:
import List from './List';
this.handleItemDel =this.handleItemDel.bind(this)
相應(yīng)的頁需要改造下List組件代碼:
import Reactfrom 'react';
const List = ({list,handleItemDel}) =>
? ? ? ?{
list.map(data => [
data.status ===1 ?
? ? ? ? ? ? ? ? ? ? ? ?{data.title}
handleItemDel(data.id)}>刪除
? ? ? ? ? ? ? ? ? ?:
null
? ? ? ? ? ?])
}
;
export default List;
這就是父組件給子組件,傳遞狀態(tài)及方法的示列!
子組件接收到父組件狀態(tài),進(jìn)行渲染。用戶點(diǎn)擊刪除,子組件調(diào)用父組件刪除方法,進(jìn)行刪除。
我們來把三塊內(nèi)容寫出來:
這里下需要修改下?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;
?}
}
現(xiàn)在三塊內(nèi)容顯示的都是一樣的,我們來區(qū)分一下,那么我們就要給子組件轉(zhuǎn)遞一個(gè)標(biāo)識(shí),告訴子組件,當(dāng)前應(yīng)該渲染那一部分內(nèi)容!
我們?cè)O(shè)定傳一個(gè)type?給子組件,并且規(guī)定 0?是全部 、1是未刪除、2是已刪除
? ?
? ? ? ?全部
? ?
? ? ? ?未刪除
? ?
? ? ? ?已刪除
然后我們修改下,List組件:
{
list.map(data => [
type ===0 ?
? ? ? ? ? ? ? ?{data.title}
handleItemDel(data.id)}>刪除
? ? ? ? ? ?:
type ===1 && data.status ===1 ?
? ? ? ? ? ? ? ? ? ?{data.title}
handleItemDel(data.id)}>刪除
? ? ? ? ? ? ? ?:
type ===2 && data.status ===0 ?
? ? ? ? ? ? ? ? ? ? ? ?{data.title}
handleItemDel(data.id)}>刪除
? ? ? ? ? ? ? ? ? ?:
null
? ?])
}
看下瀏覽器
2、未刪除后面有刪除按鈕
3、已刪除后面恢復(fù)按鈕
這兩個(gè)需求我們一起來實(shí)現(xiàn)
首先,未刪除的現(xiàn)在有刪除按鈕,我們先把已刪除那塊內(nèi)容,按鈕變成恢復(fù)按鈕,并寫上邏輯
修改 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})
}
? ?已刪除
看下瀏覽器
目前已經(jīng)可以恢復(fù)了!
我們還得修改下,全部這一塊的按鈕,
為了直觀一點(diǎn),我們加上樣式!
.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
修改下List?組件
{
data.status ===1 ?
handleItemDel(data.id)}className="del">刪除
? ? ? ?:
handleItemRecovery(data.id)}className="recovery">恢復(fù)
}
以上兩個(gè)組件完整代碼如下:
TodoList.jsx
import Reactfrom 'react';
import List from './List';
import '../../../public/css/todoList.pcss';
class TodoListextends 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 (
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?添加
? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ?全部
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ?未刪除
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ?已刪除
? ? ? ?);
? ?}
}
export default TodoList;
List.jsx
import Reactfrom 'react';
const List = ({list, handleItemDel, type, handleItemRecovery}) =>
? ? ? ?{
list.map(data => [
type ===0 ?
? ? ? ? ? ? ? ? ? ? ? ?{data.title}
{
data.status ===1 ?
handleItemDel(data.id)}className="del">刪除
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?:
handleItemRecovery(data.id)}className="recovery">恢復(fù)
? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ?:
type ===1 && data.status ===1 ?
? ? ? ? ? ? ? ? ? ? ? ? ? ?{data.title}
handleItemDel(data.id)}className="del">刪除
? ? ? ? ? ? ? ? ? ? ? ?:
type ===2 && data.status ===0 ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?{data.title}
handleItemRecovery(data.id)}className="recovery">恢復(fù)
? ? ? ? ? ? ? ? ? ? ? ? ? ?:
null
? ? ? ? ? ?])
}
;
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;
?}
}
我們來看下瀏覽器效果。
本文完
禁止擅自轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)?jiān)诠娞?hào)中留言聯(lián)系我們!
感謝童鞋們支持!
如果你有什么問題,可以在下方留言給我們!