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

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

    项目源码:

    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

    参考链接:

    https://cloud.tencent.com/developer/article/1468196

    https://react.docschina.org/docs/hooks-intro.html

    重要代码:

    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号新增加的:

  • 相关阅读:
    大端模式与小端模式
    通过tcp socket实现Linux与windows之间的文件传输
    关于递归的几个小例子
    关于线性表的一些简单应用
    数据结构(c语言实现)--线性表
    简单实现getpwnam()
    chapter 7 内存分配函数
    chapter6 非局部跳转函数 setjmp()与longjmp()
    Xcode 出现Permission denied 解决方法
    关于ARfoundation ILRuntime热更新项目的坑
  • 原文地址:https://www.cnblogs.com/xutongbao/p/11915670.html
Copyright © 2011-2022 走看看