0
点赞
收藏
分享

微信扫一扫

使用react hook做一个小型完整项目(包括二级路由,动态路由,redux,tab切换,列表跳详情,登录, 守卫)


Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 

使用react hook做一个小型完整项目(包括二级路由,动态路由,redux,tab切换,列表跳详情,登录, 守卫)_hook

项目源码:

​​https://github.com/baweireact/m-app-1705E/tree/master/16%E4%B9%A6%E6%9E%B6%EF%BC%88hook%E7%89%88%EF%BC%89​​

参考链接:

​​干货 | React Hook的实现原理和最佳实践 - 云+社区 - 腾讯云​​

​​Hook 简介 – React​​

重要代码:

Nav.js:

import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import axios from 'axios'

const Nav = (props) => {

const handleNav = (index, id) => {
props.onSetState('currentIndex', index)
props.onSetState('currentId', id)
axios({
url: `/api/get_list?id=${id}`
}).then(res => {
if (res.data.code === 200) {
props.onSetState('contentList', res.data.data)
}
})
}

useEffect(() => {
axios({
url: '/api/get_nav'
}).then(res => {
if (res.data.code === 200) {
props.onSetState('navList', res.data.data)
}
})

axios({
url: `/api/get_list?id=0`
}).then(res => {
if (res.data.code === 200) {
props.onSetState('contentList', res.data.data)
}
})
}, [])

let { navList, currentIndex } = props
let navListDom = navList.map((item, index) => (
<span
key={item.id}
className={"m-nav-item " + (currentIndex === index ? 'active' : '')}
onClick={handleNav.bind(this, index, item.id)}>
{item.title}
</span>
))

return (
<div>
{navListDom}
</div>
)
}

const mapStateToProps = (state) => {
return {
navList: state.navList,
currentIndex: state.currentIndex
}
}

const mapDispatchToProps = (dispatch) => {
return {
onSetState(key, value) {
dispatch({ type: 'SET_STATE', key, value })
}
}
}

export default connect(mapStateToProps, mapDispatchToProps)(Nav)

BookList.js:

import React from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import axios from 'axios'

const BookList = (props) => {

const handleDetail = (id) => {
props.history.push('/index/home/detail/' + id)
}

const handleAdd = (item) => {
if (!localStorage.getItem('username')) {
props.history.push('/login')
}
axios({
url: '/api/add_book',
data: {
item
},
method: 'post'
}).then(res => {
if (res.data.code === 200) {
let { currentId } = props
axios({
url: `/api/get_list?id=${currentId}`
}).then(res => {
if (res.data.code === 200) {
props.onSetState('contentList', res.data.data)
}
})
}
})
}

let { contentList } = props

let listDom = contentList.map(item => (
<div key={item.id}>
{item.title}<button onClick={handleDetail.bind(this, item.id)}>详情</button>
<button onClick={handleAdd.bind(this, item)} className={'m-add-btn ' + (item.is_in_my_book ? "" : 'active')}>收藏</button>
</div>
))

return (
<div>
{listDom}
</div>
)
}

const mapStateToProps = (state) => {
return {
contentList: state.contentList,
currentId: state.currentId
}
}

const mapDispatchToProps = (dispatch) => {
return {
onSetState(key, value) {
dispatch({ type: 'SET_STATE', key, value })
}
}
}

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(BookList))

MyBook.js:

import React, { useState, useEffect } from 'react'
import { connect } from 'react-redux'
import axios from 'axios'

const MyBook = (props) => {
const [selected, setSelected] = useState([])
const [selectAll, setSelectAll] = useState(false)


const handleSelected = (id, e) => {
let { myBook } = props
let selectedClone = JSON.parse(JSON.stringify(selected))
let index = selectedClone.findIndex(item => item === id)
if (e.target.checked) {
selectedClone.push(id)
} else {
selectedClone.splice(index, 1)
}
setSelected(selectedClone)
setSelectAll(selectedClone.length === myBook.length)
}

const handleDelete = (ids) => {
axios({
url: '/api/delete_book',
data: {
ids
},
method: 'post'
}).then(res => {
if (res.data.code === 200) {
props.onSetState('myBook', res.data.data)
}
})
}

const handleDeleteMore = () => {
axios({
url: '/api/delete_book',
data: {
ids: selected
},
method: 'post'
}).then(res => {
if (res.data.code === 200) {
props.onSetState('myBook', res.data.data)
}
})
}

const handleSelectAll = (e) => {
let { myBook } = props
setSelectAll(e.target.checked)
if (e.target.checked) {
let selected = myBook.map(item => item.id)
setSelected(selected)
} else {
setSelected([])
}
}

useEffect(() => {
axios({
url: '/api/get_my_book'
}).then(res => {
if (res.data.code === 200) {
props.onSetState('myBook', res.data.data)
}
})
}, [])

useEffect(() => {
console.log(selected)
})


let { myBook } = props

let myBookDom = myBook.map(item => (
<div key={item.id}>
<input type="checkbox" checked={selected.findIndex(id => id === item.id) >= 0 ? true : false} onChange={handleSelected.bind(this, item.id)} />
{item.title}
<button onClick={handleDelete.bind(this, [item.id])}>删除</button>
</div>
))

return (
<div>
<input type="checkbox" checked={selectAll} onChange={handleSelectAll.bind(this)}></input>全选
<button onClick={handleDeleteMore.bind(this)}>删除</button>
{myBookDom}
</div>
)
}

const mapStateToProps = (state) => {
return {
myBook: state.myBook
}
}

const mapDispatchToProps = (dispatch) => {
return {
onSetState(key, value) {
dispatch({ type: 'SET_STATE', key, value })
}
}
}

export default connect(mapStateToProps, mapDispatchToProps)(MyBook)

hook是2019年2月6号新增加的:

使用react hook做一个小型完整项目(包括二级路由,动态路由,redux,tab切换,列表跳详情,登录, 守卫)_hooks_02

使用react hook做一个小型完整项目(包括二级路由,动态路由,redux,tab切换,列表跳详情,登录, 守卫)_react hook_03

举报

相关推荐

0 条评论