hooks 系列九:hooks 实战

快来加入我们吧!

"小和山的菜鸟们",为前端开发者提供技术相关资讯以及系列基础文章。为更好的用户体验,请您移至我们官网小和山的菜鸟们 ( https://xhs-rookies.com/ ) 进行学习,及时获取最新文章。

"Code tailor" ,如果您对我们文章感兴趣、或是想提一些建议,微信关注 “小和山的菜鸟们” 公众号,与我们取的联系,您也可以在微信上观看我们的文章。每一个建议或是赞同都是对我们极大的鼓励!

实战案例:留言功能

我们学完了 react-hooks 的一些基础内容,现在是我们的一个实战环节。

项目的功能与我们的 React 教程内容相似。具体可参考,React 系列 - 实战案例:增加登录

效果

我们要做的实战很简单,就是一个简单的留言功能。

效果图:

DPIfpo6FKOvNB5g.gif

Login 页面

登录状态维护

如果我们登录成功之后,我们应该需要有一个用来存放信息的地方,为之后进行鉴权做准备,我们采用 localStorage 来做数据持久化处理。

this.props.history.replace('/home')
window.localStorage.islogin = '1'
鉴权跳转到首页

我们需要在登录页面鉴权,我们让 login 页面在加载完成的时候判断,如果已经登录过了,那么我们就跳转到 home 主页,而要达到这样的效果就需要在 useEffect() 中,在页面展示之前进行判断。

useEffect(() => {
  let localStorage = window.localStorage
  if (localStorage.islogin === '1') {
    props.history.replace('/home')
  }
})
登录页全部代码

用两个 useState() 来记录用户输入的账号密码,然后用于登录验证。

import React, { useEffect, useState } from 'react'
import './login.css'

function Login(props) {
  useEffect(() => {
    let localStorage = window.localStorage
    if (localStorage.islogin === '1') {
      props.history.replace('/home')
    }
  })

  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')

  return (
    <div className="login">
      <h2>欢迎来到XXX博客区</h2>
      <form className="form">
        <div className="formItem">
          <label htmlFor="username">用户名:</label>
          <input
            type="text"
            id="username"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
          />
        </div>
        <div className="formItem">
          <label htmlFor="password">密码:</label>
          <input
            type="password"
            id="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
        </div>
        <div className="loginBtn" onClick={() => handleLogin()}>
          登录
        </div>
      </form>
    </div>
  )

  function handleLogin() {
    if (username && password) {
      props.history.replace('/home')
      window.localStorage.islogin = '1'
      alert('欢迎!')
    } else {
      alert('请输入用户名和密码!')
    }
  }
}

export default Login

Home 页面

import React, { useState } from 'react'
import Comment from './comment'
import checkRole from './checkRole'
import './App.css'

function App(props) {
  const [title, setTitle] = useState('Hello Hooks')
  const [desc, setDesc] = useState(
    '你知道有这么一个团队吗?他们怀揣梦想,艰苦奋斗,作为一群大学生菜鸟,放弃了平时娱乐的时间,选择一起学习,一起成长,将平时学习的笔记,心得总结为文章,目的很简单,希望可以帮助向他们一样的菜鸟们?你想了解更多吗?快搜索微信公众号:小和山的菜鸟们,加入他们吧!',
  )
  const [comments, setComments] = useState([
    {
      headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png',
      time: new Date(2021, 4, 14, 21, 2, 30),
      nickName: '小菜鸟',
      detail: '这是一个即将推出系列文章的团队,我们一起期待他们的作品吧!',
      liked: true,
      likeNum: 23,
    },
  ])
  const [text, setText] = useState('')

  return (
    <div className="App">
      <span className="logout" onClick={handleLogout}>
        退出登录
      </span>
      <h2>{title}</h2>
      <div className="desc">{desc}</div>
      <div style={{ width: '100%' }}>
        <p className="commentsTitle">评论</p>
        {comments.map((item, index) => {
          return (
            <Comment key={item.time.getTime()} changeLike={() => changeLike(index)} {...item} />
          )
        })}
      </div>

      <div className="newComment">
        <div style={{ display: 'flex' }}>
          <img src="https://xhs-rookies.com/img/rookie-icon.png" className="" alt="" />
          <textarea value={text} onChange={changeText} placeholder="请输入评论" />
        </div>

        <div className="submit" onClick={addComment}>
          发表
        </div>
      </div>
    </div>
  )
  // 退出登录
  function handleLogout() {
    window.localStorage.islogin = '0'
    props.history.replace('/login')
  }
  // 改变text
  function changeText(e) {
    setText(e.target.value)
  }

  function changeLike(index) {
    let newArray = [...comments]
    let newItem = { ...newArray[index] }
    if (newItem.liked) {
      newItem.liked = false
      newItem.likeNum -= 1
    } else {
      newItem.liked = true
      newItem.likeNum += 1
    }
    newArray[index] = newItem
    setComments(newArray)
  }

  function addComment() {
    if (!text) {
      alert('请输入留言内容')
      return
    }
    let detail = text
    setText('')
    let newComment = {
      headPortrait: 'https://xhs-rookies.com/img/rookie-icon.png',
      time: new Date(),
      nickName: '小菜鸟',
      detail,
      liked: false,
      likeNum: 0,
    }
    setComments([newComment, ...comments])
  }
}

export default App

用到的组件

comment 组件

这个组件是用来显示用户留言的,按数据展示。

import React from 'react'
import './comment.css'

function Comment(props) {
  const { nickName, time, headPortrait, detail, liked, likeNum, changeLike } = props
  return (
    <div className="comment">
      <div className="info">
        <img src={headPortrait} alt="头像" />
        <div>
          <p className="nickname">{nickName}</p>
          <p className="time">{getTime(time)}</p>
        </div>
      </div>
      <div className="detail" style={{ marginBottom: '10px' }}>
        {detail}
      </div>
      <div className="toolBox">
        <span className={'likeBox ' + (liked ? 'like' : 'unlike')} onClick={changeLike}>
          <span className="icon"> </span>
          <span>{!!likeNum && likeNum}</span>
        </span>
        <span className="share icon"> </span>
      </div>
    </div>
  )

  function getTime(time) {
    const year = time.getFullYear()
    const month = time.getMonth() + 1
    const day = time.getDate()
    const hour = String(time.getHours()).padStart(2, '0')
    const minute = String(time.getMinutes()).padStart(2, '0')
    const second = String(time.getSeconds()).padStart(2, '0')
    return `${year}.${month}.${day}  ${hour}:${minute}:${second}`
  }
}

export default Comment

总结

到这里,我们的 hooks 实战就已经结束了,虽然只是一个简单的留言功能,但是也包含了 hooks 的一些用法。

如果需要查看源码的话,可以查看并下载我们的开源库项目 github 地址

下节预告

hooks 的学习到此已经告一段落,接下来在这个金九银十的时间段,我们将为大家带来精彩的面试题目,敬请期待!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Hooks是React 16.8版本中新增的特性,它提供了一种在函数组件中使用状态和其他React特性的方式。使用Hooks可以使函数组件具备类组件的功能,而不需要使用类组件的繁琐语法和复杂的生命周期方法。在实际项目中使用React Hooks可以带来更好的开发体验和代码复用。 在使用React Hooks进行实战时,可以通过useState和useEffect等Hook来处理组件中的状态和副作用。useState可以用于在函数组件中创建和管理状态,而useEffect可以用于处理副作用操作,例如发送网络请求和订阅事件等。同时,还可以使用其他常用的Hooks,比如useRef和useCallback等。 在团队协作方面,引入React Hooks可能会导致团队成员对于Hooks的水平不一致。一些常见的问题包括闭包问题和依赖死循环等。解决闭包问题可以使用不同的方法,React官方并没有给出太多的最佳实践,所以团队成员需要通过实践摸索出适合自己的方式。此外,在刚接触Hooks时,团队成员可能只熟悉useState和useEffect这两个最常用的Hooks,对于其他常用的Hooks的使用场景可能不太清楚。 为了避免一些常见的问题,可以定期在团队内分享React Hooks的最佳实践,引导团队成员更好地理解和使用Hooks。对于那些不喜欢使用React Hooks的成员,可以继续使用类组件,因为类组件在某些方面可能更容易理解和调试。React Hooks只是一种工具,会使用它会提升开发效率,但不使用也不会影响其他人的代码。因此,类组件和函数组件可以共存。 总之,React Hooks是一个强大的工具,可以在函数组件中使用状态和其他React特性。在实际项目中,使用React Hooks可以带来更好的开发体验和代码复用,但需要注意团队成员之间的水平差异和常见问题的解决方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [React hooks实战总结](https://blog.csdn.net/sinat_17775997/article/details/100014480)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [React-Hook最佳实践](https://blog.csdn.net/xiaofeng123aazz/article/details/127361597)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值