快来退出咱们吧!

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

"Code tailor" ,如果您对咱们文章感兴趣、或是想提一些倡议,微信关注 “小和山的菜鸟们” 公众号,与咱们取的分割,您也能够在微信上观看咱们的文章。每一个倡议或是同意都是对咱们极大的激励!

实战案例:留言性能

咱们学完了 react-hooks 的一些根底内容,当初是咱们的一个实战环节。

我的项目的性能与咱们的 React 教程内容类似。具体可参考,React 系列 - 实战案例:减少登录

成果

咱们要做的实战很简略,就是一个简略的留言性能。

效果图:

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 的学习到此曾经告一段落,接下来在这个金九银十的时间段,咱们将为大家带来精彩的面试题目,敬请期待!