前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >hook+react-redux让redux使用更简单

hook+react-redux让redux使用更简单

作者头像
源心锁
发布2022-08-12 11:30:16
7720
发布2022-08-12 11:30:16
举报
文章被收录于专栏:前端魔法指南

我想,redux的名声在前端领域里应该是非常响亮的。而对应的,它的社区也是非常活跃,因此,当我们希望在一个React项目中引入redux进行状态管理的话,我们只需要引入react-redux

下边的例子中,会引入redux-thunk让store支持异步更新

redux核心概念

  • store
  • action
  • reducer

实际上,在react-redux中我们只需要了解这三个概念即可使用redux,而实际上这些也不难理解。我们只要掌握一些关键的api,尤其是hook,就可以很轻松地在我们的项目中加入redux

store

store的概念是什么?我们完全可以将store当成一个state总仓库,当成一个超大的state

正常来讲 组件与组件之间传值的关系是这样的

image.png
image.png

我们可以看到,当我们试图把father组件的state值传到child-2-1这个三级组件,并且保证每次更新state可以使得child-2-1接收到,在没有hook之前我们不得不一层层把state下传,这无疑让组件的可维护性大大降低,增加了很多繁杂的代码。

引入redux 而在我们引入redux后,结构关系就变成了这样

image.png
image.png

我们的放在store中的state不必再依赖于层层传递,当store中我们希望获得的state更新的时候,会触发通知到订阅了该state的组件,从而完成视图更新

然众所周知万事开头难,我们把store.js的文件代码直接放上,这里可以直接抄

  • store.js
代码语言:javascript
复制
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from "../reducers";

// 添加支持浏览器redux插件
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  rootReducer,
  composeEnhancers(applyMiddleware(thunk))
);

export default store;

action

action是触发store中state更新的行为

其实也非常好理解,我们还是先看看原本的state更新。可以看到,直接修改组件的state是无法触发视图层更新的。在store中,类似的,store中的state是只读的,我们想要更新store中的state,只能通过预先制定好的action触发更新。

代码语言:javascript
复制
// class组件
this.setState({
    state0:1
})
// function组件
function Component(){
    const [state0,setState0]=useState(0);
    setState0(1);
}
//错误做法
this.state0=1

而使用redux的话,通常我们用这种形式更新

代码语言:javascript
复制
dispatch({
   type:"setState0",
   payload:1
})

注意这里的dispatch和上方的setState作用上是类似的,而action是它发出去的内容

  • action框架
代码语言:javascript
复制
const controlNav = () => dispatch => {
    dispatch({
      type: "controlNav"
    })
  };
export {controlNav}

reducer

我们上边讲到了action,但action发出后当然不是直接更新state,实际上,store收到action后,要先经过reducer处理,才可以更新相关的state

代码语言:javascript
复制
const initialState={
    state0:0
}
const navReducer = (state = initialState, action) => {
    switch (action.type) {
        case "setState0":
            state.state0=action.payload
            return {...state}
        case "clearState0":
            state.state0=0
            return {...state}
        default:
            return state;
    }
}

这里值得注意的是,更新是需要进行深拷贝的,并且reducer应该是纯函数

  • reducers目录
代码语言:javascript
复制
import {combineReducers} from "redux";

import linkReducer from "./linkReducer";
import navReducer from "./navReducer";
import workspaceReducer from "./workspaceReducer";
import orderReducer from "./orderReducer";

const rootReducer = combineReducers({
    linkReducer,navReducer,workspaceReducer,orderReducer
});

export default rootReducer;

那么最好形成的目录结构如下:

image.png
image.png

用hook简化操作

useSelector 接收state的更新

代码语言:javascript
复制
function WorkSpace(){
    const initData=useSelector(item=>item.workspaceReducer.initData)
}

当我们更新initData的时候,组件WorkSpace中的initData会收到更新并且重新渲染组件

useDispatch 发出action从而更新state

我们可以通过dispatch在组件中更新store中的state

代码语言:javascript
复制
import { handleWorkSpaceShow } from "../../../actions/workspace";
function Workspace() {
  const dispatch = useDispatch();
  dispatch(handleWorkSpaceShow());
}

对应的action

这其中的handleWorkSpaceShow是一个action,具体如下:

代码语言:javascript
复制
const handleWorkSpaceShow = (val) => (dispatch) => {
  dispatch({
    type: "handleWorkSpaceShow",
    payload:{
      data:val
    }
  })
};

对应的reducer

然后对应"handleWorkSpaceShow"这个type,reducer是这样工作的

代码语言:javascript
复制
const workspaceReducer = (state = initialState, action) => {
  switch (action.type) {
    case "handleWorkSpaceShow":
      state.running = action.payload.data;
      state.startTimeStamp = new Date().getTime();
      return { ...state };
    default:
      return { ...state };
  }
};

通过上述步骤,其实我们就已经可以对store进行维护

当然别忘了,事先要在最外层加一层Provider:

代码语言:javascript
复制
ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <Router>
        <Suspense fallback={<div>Loading...</div>}>
          <Route path="/net" component={Nav} />
          <Route path="/net" component={NetIndex} />
          <Route path="/login" component={Login} />
        </Suspense>
      </Router>
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • redux核心概念
    • store
      • action
        • reducer
        • 用hook简化操作
          • useSelector 接收state的更新
            • useDispatch 发出action从而更新state
              • 对应的action
                • 对应的reducer
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档