Redux重构大实战(下):Footer组件的状态管理
2024-01-17 10:29:38
前言
随着 Taro 的不断迭代,小程序开发更加便捷和高效。在本文中,我们将继续使用 Hooks 版的 Redux 重构 Taro 项目,并在此基础上进一步实现项目的状态管理。在上一篇中,我们已经完成了 user 部分的状态管理的重构,受限于篇幅,我们还剩下 Footer 组件部分没有重构。因此,在这一篇中,我们将首先实现 Footer 组件的状态管理的重构,接着我们马上来实现 post 逻辑的状态管理,完成整个项目的重构。有兴趣的同学,可以跟着一起来实现看看哦~
Footer 组件的状态管理重构
Footer 组件是一个简单的组件,它负责显示应用程序的底部导航栏。它的状态非常简单,只有两个属性:active
和 items
。active
属性用于指示当前选中的导航栏项,而 items
属性则用于存储导航栏项的列表。
在使用 Hooks 版的 Redux 重构之前,Footer 组件的状态管理代码如下:
import React from 'react'
import { connect } from 'react-redux'
const Footer = (props) => {
const { active, items } = props
return (
<footer className="footer">
<ul className="footer-nav">
{items.map((item) => (
<li key={item.id} className={active === item.id ? 'active' : ''}>
<a href={item.href}>{item.text}</a>
</li>
))}
</ul>
</footer>
)
}
const mapStateToProps = (state) => ({
active: state.footer.active,
items: state.footer.items,
})
export default connect(mapStateToProps)(Footer)
使用 Hooks 版的 Redux 重构后,Footer 组件的状态管理代码如下:
import React from 'react'
import { useSelector } from 'react-redux'
const Footer = () => {
const active = useSelector((state) => state.footer.active)
const items = useSelector((state) => state.footer.items)
return (
<footer className="footer">
<ul className="footer-nav">
{items.map((item) => (
<li key={item.id} className={active === item.id ? 'active' : ''}>
<a href={item.href}>{item.text}</a>
</li>
))}
</ul>
</footer>
)
}
export default Footer
可以看出,使用 Hooks 版的 Redux 重构后,Footer 组件的状态管理代码更加简洁和易读。同时,它也与 React 的函数式组件语法更加一致。
post 逻辑的状态管理重构
接下来,我们来实现 post 逻辑的状态管理的重构。post 逻辑是 Taro 项目中比较复杂的一部分,它负责管理帖子列表的显示和编辑。它的状态也比较复杂,包括帖子列表、当前选中的帖子、以及帖子的编辑状态等。
在使用 Hooks 版的 Redux 重构之前,post 逻辑的状态管理代码如下:
import React, { useState, useEffect } from 'react'
import { connect } from 'react-redux'
const PostList = (props) => {
const [posts, setPosts] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((res) => res.json())
.then((data) => {
setPosts(data)
setLoading(false)
})
.catch((err) => {
setError(err)
setLoading(false)
})
}, [])
const handleEditPost = (post) => {
props.dispatch({ type: 'SET_EDIT_POST', post })
}
const handleDeletePost = (post) => {
props.dispatch({ type: 'DELETE_POST', post })
}
return (
<ul className="post-list">
{loading ? (
<li>Loading...</li>
) : error ? (
<li>Error: {error.message}</li>
) : (
posts.map((post) => (
<li key={post.id}>
<a href="#" onClick={() => handleEditPost(post)}>{post.title}</a>
<button onClick={() => handleDeletePost(post)}>Delete</button>
</li>
))
)}
</ul>
)
}
const PostEditor = (props) => {
const [title, setTitle] = useState(props.post ? props.post.title : '')
const [body, setBody] = useState(props.post ? props.post.body : '')
const handleSavePost = () => {
props.dispatch({ type: 'SAVE_POST', post: { id: props.post ? props.post.id : null, title, body } })
}
return (
<form className="post-editor">
<input type="text" value={title} onChange={(e) => setTitle(e.target.value)} />
<textarea value={body} onChange={(e) => setBody(e.target.value)}></textarea>
<button onClick={handleSavePost}>Save</button>
</form>
)
}
const mapStateToProps = (state) => ({
posts: state.post.posts,
editPost: state.post.editPost,
})
export default connect(mapStateToProps)(PostList)
export default connect(mapStateToProps)(PostEditor)
使用 Hooks 版的 Redux 重构后,post 逻辑的状态管理代码如下:
import React, { useState, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
const PostList = () => {
const posts = useSelector((state) => state.post.posts)
const loading = useSelector((state) => state.post.loading)
const error = useSelector((state) => state.post.error)
const dispatch = useDispatch()
useEffect(() => {
dispatch({ type: 'FETCH_POSTS' })
}, [])
const handleEditPost = (post) => {
dispatch({ type: 'SET_EDIT_POST', post })
}
const handleDeletePost = (post) => {
dispatch({ type: 'DELETE_POST', post })
}
return (
<ul className="post-list">
{loading ? (
<li>Loading...</li>
) : error ? (
<li>Error: {error.message}</li>
) : (
posts.map((post) => (
<li key={post.id}>
<a href="#" onClick={() => handleEditPost(post)}>{post.title}</a>
<button onClick={() => handleDeletePost(post)}>Delete</button>
</li>
))
)}
</ul>
)
}
const PostEditor = () => {
const editPost = useSelector((state) => state.post.editPost)
const dispatch = useDispatch()
const [title, setTitle] = useState(editPost ? editPost.title : '')
const [body, setBody] = useState(editPost ? editPost.body : '')
const handleSavePost = () => {
dispatch({ type: 'SAVE_POST', post: { id: editPost ? editPost.id : null, title, body } })
}
return (
<form className="post-editor">
<input type="text" value={title} onChange={(e) => setTitle(e.target.value)} />
<textarea value={body} onChange={(e) => setBody(e.target.value)}></textarea>
<button onClick={handleSavePost}>Save</button>
</form>
)
}
export default PostList
export default PostEditor
可以看出,使用 Hooks 版的 Redux 重构后,post 逻辑的状态管理代码更加简洁和易读。同时,它也与 React 的函数式组件语法更加一致。
总结
通过本文,我们完成了 Taro 项目的状态管理的重构。在重构过程中,我们使用了 Hooks 版的 Redux,使代码更加简洁和易读。同时,我们也遵循了 React 的函数式组件语法,使代码更加一致和易于维护。
希望