Redux在React中快速应用

第一步 装包

在项目文件夹下,用npm安装 redux和react-redux插件

  1. npm i redux react-redux -S

第二步 Redux的使用

Reducer

第一步 创建 reducers 文件夹

在数据比较复杂的情况下将 Reducer 拆分为独立的函数或文件

因为我们需要两个数据所以这里我们 将Reducer拆分。

首先在项目文件夹的src中创建reducers文件夹

  1. [项目文件夹] -> src -> reducers

第二步reducers写入 comment 的StateAction

在 reducer 文件夹内创建 comment.js文件

  1. reducers -> comment.js

在comment.js内写入 state 数据

  1. let comments = [
  2. {
  3. content: '多好的一呀',
  4. postId: '1'
  5. },
  6. {
  7. content: '真是不错',
  8. postId: '1'
  9. },
  10. {
  11. content: '多好的二呀',
  12. postId: '2'
  13. }
  14. ]

再写入 Reducer 函数

  1. export default function commentReducer(state = comments, action) {
  2. //将state指向comment
  3. switch (action.type) {
  4. case 'ADD_COMMENT':
  5. //action函数的type
  6. return [...state ,{ postId: action.postId, content: action.comment }]
  7. //返回一个新的 state 数组
  8. default:
  9. return state;
  10. //如果出错返回 旧的 state
  11. }
  12. }

第三步 创建 post 的 Reducer 函数

创建 post.js 文件,写入 Reducer 函数

  1. let posts = [
  2. {
  3. postId: '1',
  4. likes: 1,
  5. title: 'Git 技巧'
  6. },
  7. {
  8. postId: '2',
  9. likes: 2,
  10. title: '学习 Redux'
  11. }
  12. ]
  13. export default function postReducer(state = posts, action) {
  14. switch (action.type) {
  15. case 'INCREMENT_LIKE':
  16. let stateCopy = state.slice()
  17. //拷贝 state 数据
  18. stateCopy.map(item => {
  19. if(item.postId === action.postId){
  20. item.likes++
  21. return item
  22. }
  23. return item
  24. })
  25. //实现liskes的 ++
  26. return stateCopy
  27. //返回新的 state
  28. default:
  29. return state
  30. }
  31. }

第四步 将独立的 Reducer 合成

在 Reducers 文件夹下 创建 index.js 文件

  1. reducers -> index.js

利用 combineReducers 函数将单个的 Reducer 合成到 rootReducer 里

  1. import { combineReducers } from 'redux'
  2. //导入 redux 的 combineReducers 函数
  3. import commentReducer from './comment'
  4. //导入 commentReducer
  5. import postReducer from './post'
  6. //导入 commentReducer
  7. const rootReducer = combineReducers({
  8. comments: commentReducer,
  9. posts: postReducer
  10. })
  11. //利用 combineReducers 合成 Reducer 到 rootReducer 中
  12. export default rootReducer
  13. //默认导出 rootReducer

第五步 创建 Redux store

在 src 文件夹下创建 store.js 文件

  1. [项目文件夹] -> src -> store.js

创建 store 状态树

  1. import { createStore } from 'redux';
  2. //导入 redux 的 createStore 函数
  3. import rootReducer from './reducers/'
  4. //导入 reducer
  5. //利用 createStore 函数创建 Redux store
  6. let store = createStore(rootReducer)
  7. //给 createStore 传入 reducer 参数
  8. export default store
  9. //默认导出 store

第六步 给组件注入 store 中的 state 数据

在入口文件中利用 react-redux 的<Provider>组件导入 store

  1. import React, { Component } from 'react'
  2. import store from './store'
  3. //导入store
  4. import { Provider } from 'react-redux'
  5. //导入 react-redux 的 Provider 组件
  6. import HomePage from './HomePage'
  7. import PostPage from './PostPage'
  8. import './App.css'
  9. import {
  10. BrowserRouter as Router,
  11. Route,
  12. Switch,
  13. Link
  14. } from 'react-router-dom'
  15. const Header = () => (
  16. <Link to="/" className="back-home">首页</Link>
  17. )
  18. class App extends Component {
  19. render() {
  20. return (
  21. <Provider store={store}>
  22. //将组件用Provider插件包裹 将 store 传入
  23. <Router>
  24. <div>
  25. <Header />
  26. <Switch>
  27. <Route exact path="/" component={HomePage} />
  28. <Route path="/post/:id" component={PostPage} />
  29. </Switch>
  30. </div>
  31. </Router>
  32. </Provider>
  33. )
  34. }
  35. }
  36. export default App;

拿取到 store 中的数据

利用 React-Redux 的 connect 拿到 store 中数据

  1. import React, { Component } from 'react'
  2. import { connect } from 'react-redux'
  3. //导入 connect 组件
  4. class PostBody extends Component {
  5. render() {
  6. return (
  7. <div>
  8. {this.props.comments.length}
  9. //通过 this.props 拿到需要的数据
  10. </div>
  11. )
  12. }
  13. }
  14. //声明一个 mapStateToProps 函数拿到需要的数据
  15. const mapStateToProps = (state) => ({
  16. comments: state.comments
  17. //名称:拿到 state.comments 数据
  18. })
  19. //将 mapStateToProps 作为 connect 的一个参数传入
  20. export default connect(mapStateToProps)(PostBody)
  21. //用connect导出 PostBody组件

操作 state 数据

store 中的数据不能直接修改,需要拷贝一个新数据进行修改

这里我们使用dispatch()调用 Action 来进行对数据的操作

  1. import React, { Component } from 'react'
  2. import { connect } from 'react-redux'
  3. import store from './store'
  4. import {
  5. Link
  6. } from 'react-router-dom'
  7. class PostBody extends Component {
  8. like = () => {
  9. store.dispatch({ type: 'INCREMENT_LIKE', postId: this.props.postId })
  10. //通过type来确定action调用的方法
  11. //通过postId来进行修改数据
  12. }
  13. render() {
  14. let { postId, posts } = this.props
  15. let currentPost = posts.filter(value => value.postId === postId )[0]
  16. return (
  17. <div className="post-body">
  18. <Link to={`/post/${postId}`} className="title">
  19. {currentPost.title}
  20. </Link>
  21. <div onClick={this.like} className="likes-num num">
  22. {currentPost.likes}
  23. </div>
  24. <div className="comment-num num">
  25. {this.props.comments.length} 评论
  26. </div>
  27. </div>
  28. );
  29. }
  30. }
  31. const mapStateToProps = (state) => ({
  32. comments: state.comments,
  33. posts: state.posts
  34. })
  35. export default connect(mapStateToProps)(PostBody)

这样一个完整的利用 React+Redux 的项目就成功创建

参考