"小和山的菜鸟们",为前端开发者提供技术相关资讯以及系列基础文章。为更好的用户体验,请您移至咱们官网小和山的菜鸟们 ( xhs-rookies.com/ ) 进行学习,及时获取最新文章。javascript
"Code tailor" ,若是您对咱们文章感兴趣、或是想提一些建议,微信关注 “小和山的菜鸟们” 公众号,与咱们取的联系,您也能够在微信上观看咱们的文章。每个建议或是赞同都是对咱们极大的鼓励!css
咱们学完了 react-hooks 的一些基础内容,如今是咱们的一个实战环节。html
项目的功能与咱们的 React 教程内容类似。具体可参考,React 系列 - 实战案例:增长登陆前端
咱们要作的实战很简单,就是一个简单的留言功能。java
效果图:react
若是咱们登陆成功以后,咱们应该须要有一个用来存放信息的地方,为以后进行鉴权作准备,咱们采用 localStorage
来作数据持久化处理。git
this.props.history.replace('/home')
window.localStorage.islogin = '1'
复制代码
咱们须要在登陆页面鉴权,咱们让 login
页面在加载完成的时候判断,若是已经登陆过了,那么咱们就跳转到 home
主页,而要达到这样的效果就须要在 useEffect()
中,在页面展现以前进行判断。github
useEffect(() => {
let localStorage = window.localStorage
if (localStorage.islogin === '1') {
props.history.replace('/home')
}
})
复制代码
用两个 useState()
来记录用户输入的帐号密码,而后用于登陆验证。web
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
复制代码
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
复制代码
这个组件是用来显示用户留言的,按数据展现。面试
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
的学习到此已经告一段落,接下来在这个金九银十的时间段,咱们将为你们带来精彩的面试题目,敬请期待!