相关文章推荐
酒量小的眼镜  ·  从 SharePoint Online ...·  1 月前    · 
正直的剪刀  ·  spring webflux filter ...·  1 年前    · 
慷慨大方的洋葱  ·  python - ...·  1 年前    · 
干练的仙人球  ·  python - What is the ...·  1 年前    · 

Hooks 提供了很多好用的api,甚至很多人认为Hooks的 useReducer 等Api已经可以取代Redux了。其实Hooks和Redux的使用场景并不冲突,而且可以互相借鉴,最近react-edux最新版本( 7.1 )也引入了Hooks风格的Api。

useState useReducer 是Hooks中最常用的Api,适合用来进行简单的状态管理,但也都有一些无法满足的需求

useState

import React, { useState } from "react";
const ComponentUseState = () => {
  const [num, setNum] = useState(0);
  return (
      <h2>Using useState</h2>
      Number: {num}
      <button onClick={() => setNum(num + 1)}>+</button>
      <button onClick={() => setNum(num - 1)}>-</button>
    </div>
export default ComponentUseState;

useState可以用最简单的方式更新状态,但是状态更新的逻辑(例如上面例子中的加减一运算)散落在UI中,不能独立复用,也不便于测试。

useReducer

使用useReducer可以解决上面useState无法解决的问题。

import React, { useReducer } from 'react'
const initialState = {num: 0};
const reducer = (state, action) => {
  switch(action.type) {
    case 'decrement':
      return {...state, num: state.num - 1}
    case 'increment':
      return {...state, num: state.num + 1}
    default:
      return state;
const ComponentUseReducer = () => {
  const [state, dispatch] = useReducer(reducer, initialState)
  const { num } = state
  return (
      <h2>Using useReducer</h2>
      Number: {num}
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
    </div>
export default ComponentUseReducer;

可以看到useReducer的逻辑脱离了UI,可以独立复用。reducer就是一个单纯的Js方法,我们可以对reducer进行单独测试,甚至可以在chrome中进行调试

实际使用中reducer应该以单独的文件存在,上面例子为了简单起见放到了一起。

useReducer虽然很好地分离了逻辑和UI,但是无法像redux一样进行跨组件的状态共享,例如子组件无法方便的访问到num

useSelector、useDispatch

如上所述,Hooks仍然无法替代Redux的作用,特别是在状态共享方面。庆幸的是 react-redux 7.1之后也可以使用useSelector、useDispatch等HooksApi替代connect,减少模板代码。

import React from "react";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch } from "react-redux";
const initialState = { num: 0 };
const reducer = (state, action) => {
  switch (action.type) {
    case "decrement":
      return { ...state, num: state.num - 1 };
    case "increment":
      return { ...state, num: state.num + 1 };
    default:
      return state;
const store = createStore(reducer, initialState);
const ComponentUseReactRedux = () => {
  return (
      <h2>ComponentUseReactRedux</h2>
      <Provider store={store}>
        <ChildComponentUseReactRedux />
      </Provider>
    </div>
const ChildComponentUseReactRedux = () => {
  const num = useSelector(state => state.num);
  const dispatch = useDispatch();
  return (
      <h3>Using useSelector, useDispatch</h3>
      Number: {num}
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </div>
export default ComponentUseReactRedux;

createStore

通过createStore将state存入store,

const store = createStore(reducer, initialState);

再通过Provider向子组件暴露store,通过store在父子组件之间共享状态

 <Provider store={store}>
     <ChildComponentUseReactRedux />
 </Provider>

useSelector

子组件可以通过useSelector访问name

  const num = useSelector(state => state.num);

当然,也可以提出selector函数,方便替换和复用,如下

const selector = state => {
  return state.num;
const num = useSelector(selector);

useDispatch

通过useDispatch 可以获取dispatch

  const dispatch = useDispatch()

即使多几个子组件也可以共享状态

const ComponentUseReactRedux = () => {
  return (
      <h2>ComponentUseReactRedux</h2>
      <Provider store={store}>
        <ChildComponentUseReactRedux />
        <ChildComponentUseReactRedux />
      </Provider>
    </div>

通过useSelector、useDispatch等方法,我们可以用Hooks方法完成Redux的功能,Hooks和Redux之间没有替代关系,应该更好地共存和融合。

Hooks 提供了很多好用的api,甚至很多人认为Hooks的useReducer等Api已经可以取代Redux了。其实Hooks和Redux的使用场景并不冲突,而且可以互相借鉴,最近react-edux最新版本中也引入了Hooks风格的Api。useState和useReducer是Hooks中最常用的Api,适合用来进行简单的状态管理,但也都有一些无法满足的需求useStateimpo... Hooks 提供了很多好用的api,甚至很多人认为Hooks的useReducer等Api已经可以取代Redux了。其实Hooks和Redux使用场景并不冲突,而且可以互相借鉴,react-redux(7.1)也引入了Hooks风格的Api。 1.1 useState 的缺点 useState和useReducer是Hooks最常用的Api,适合用来进行简单的状态管理,但也都有一些无法满足的需求 useState可以用最简单的方式更新 const state = useSelector((a)=>(a.counter)) useSelector里面接收一个回调函数,回调函数的第一个参数是reducer的实例。 回调函数返回值可以是整个reducer实列(一般用于reducer只有一个时),也可以是实例对象里面的某个被合并的元素(reducer有多个,用combineReducers()进行了合并)。 打印回调函数的
如何在redux使用useSelectoruseDispacth来获取数据。我们可以使用mapStateToProps的替代方法useSelector。我们还可以使用mapDispatchToProps的替代方法useuseppatch。 之前使用mapStateToProps和mapDispatchToProps的示例。 import update_person from './store/actions/personAction'; import { connect } from 'react-r
React-redux 7.1发版啦。 API简单的介绍 因为在新的项目用到了hooks,但是用的时候react-redux还处于alpha.x版本的状态。用不了最新的API,感觉不是很美妙。好在,这两天发布了7.1版本。 现在来看看怎么用这个新的API。 useSelector() const result : any = useSelector(selector : Function, eq...
export const selectCount = (state) => state.counter.value; const count = useSelector(selectCount); <span className={styles.value}>{count}</span> import { useSelector, useDispatch } fr. 多的不多说 直接上代码 说实话,不太懂redux建议先看看文档 一切知识优先看文档和源码 看不懂的再去看一些机构的视频或者看某些大佬的文章 封装connect 本质上自己创建了一个上下文来取出数据state再派发出去。封装该层语法 connect语法 connect(mapStateToprops,mapDispatchToprops)(WrappedComponent) mapStateToProps 类型是个函数,作用是吧store的数据放在props上 在上下文…props解构 funct
redux大家都知道,它是第三方的react状态管理库,被很多人吐槽既难用又不得不用。我最近发现完全可以只用react官方hooks实现redux的大部分功能!使用起来比redux简便一些,代码量也少一下。 在这里我写了一个完整的demo,一般小型项目完全可以参考它,实现只用官方Hooks代替redux。以下是完整步骤和代码: 使用官方模板创建react项目: create-react-app demo 清理public/目录 删除该目录下所有文件,然后在该目录下新建index.html,内容
随着react hooks越来越火,react-redux也紧随其后发布了7.1(https://react-redux.js.org/api/hooks#using-hooks-in-a-react-redux-app)版本 首先是几个API useSelector() const result : any = useSelector(selector : Function, equa...
`useSelector` 是 Redux提供的一个 hooks,用于在 React 组件获取 Redux store 的数据。它接受一个参数,即一个回调函数,该函数定义了需要从 store 获取哪些数据。 以下是 `useSelector` 的使用示例: ```javascript import { useSelector } from 'react-redux'; const MyComponent = () => { // 从 store 获取 count 值 const count = useSelector(state => state.count); return ( <p>Count: {count}</p> 在上面的例子,回调函数 `state => state.count` 定义了我们要从 store 获取 `count` 属性的值。在组件,我们可以直接使用 `count` 变量来访问该值。 请注意,在使用 `useSelector` 之前,你需要确保已经在应用程序设置了 Redux Provider,并且 store 可以被访问到。