Dva: React Hooks和dva结合使用的问题

Created on 27 Jun 2019  ·  30Comments  ·  Source: dvajs/dva

import { connect } from 'dva';
import React, { useEffect } from 'react';

const Page = props => {
  const { dispatch, text } = props;
  useEffect(() => {
    dispatch({ type: 'xxx/fetchText' });
  }, []);

 return <div>{text}</div>
}

export default connect(({ xxx }) => ({ text: xxx.text }))(Page);

如果这样写 在检查时会被react-hooks/exhaustive-deps这条规则提示React Hook useEffect has a missing dependency: dispatch.
但是如果把dispatch加入useEffect的DependencyList里时 又会不停的执行里面的请求 请问在与dva结合使用React Hooks时应该怎么写呢

wontfix

Most helpful comment

All 30 comments

useDispatch,用了hooks了 就可以不用connect了,不过我为了偷懒,从store里取出了所有effects和reducer,通过namespace去查找后返回所有actions,参考:

function useActions(namespace) {
  const dispatch = useDispatch();

  const actions = useMemo(() => {
    const { _models } = getStore();
    const targetModel = _models.find(model => model.namespace === namespace);
    return targetModel ? Object.keys({ ...targetModel.effects, ...targetModel.reducers }).reduce((prev, curre) => {
      const actionName = curre.replace(new RegExp(`^${namespace}/`), '');
      prev[actionName] = payload => dispatch({ type: curre, payload });
      return prev;
    }, {}) : {};
  }, [namespace, dispatch]);

  return actions;
}

useDispatch,用了hooks了 就可以不用connect了,不过我为了偷懒,从store里取出了所有effects和reducer,通过namespace去查找后返回所有actions,参考:

function useActions(namespace) {
  const dispatch = useDispatch();

  const actions = useMemo(() => {
    const { _models } = getStore();
    const targetModel = _models.find(model => model.namespace === namespace);
    return targetModel ? Object.keys({ ...targetModel.effects, ...targetModel.reducers }).reduce((prev, curre) => {
      const actionName = curre.replace(new RegExp(`^${namespace}/`), '');
      prev[actionName] = payload => dispatch({ type: curre, payload });
      return prev;
    }, {}) : {};
  }, [namespace, dispatch]);

  return actions;
}

image
官方似乎已经移除了useDispatch()的用法.
现在
image 使用这种方式

@UlyC 哪里移除了,可以给个链接吗

@UlyC 哪里移除了,可以给个链接吗

是我看错了 .
是在https://reactjs.org/docs/hooks-reference.html React官方Hooks API中没有useDispatch()的用法,
这个是react-redux的用法https://react-redux.js.org/next/api/hooks#usedispatch, 要从react-redux中导入
import { useDispatch } from 'react-redux'

@UlyC 哪里移除了,可以给个链接吗

是我看错了 .
是在https://reactjs.org/docs/hooks-reference.html React官方Hooks API中没有useDispatch()的用法,
这个是react-redux的用法https://react-redux.js.org/next/api/hooks#usedispatch, 要从react-redux中导入
import { useDispatch } from 'react-redux'

= -好吧

~const dispatch = useDispatch(); hooks 是不是 dva 就不能 使其Promise化?~
dva里把effect加Promise化了

dva/umi 有没有考虑集成hooks 功能呢? 想使用的话必须import { useDispatch } from 'react-redux' 这样用么。 会不会有坑。

image

我用了,没啥问题

@yoyo837
```
import { useDispatch } from 'dva';

console.log('下午6:23:08', useDispatch)
```
我这样打印出来是undefined. 是不是要升级react-redux?到哪个版本啊

升级dva 最新beta

你最好watch一下 releases

希望升级后能更新下文档,useDispatch这个功能还没搞懂干什么的

dva是直接从react-redux导出useDispatch的,你直接看react-redux文档就可以啦

image

https://react-redux.js.org/api/hooks#usedispatch

1.升级dva到最新版本(我的版本是2.6.0-beta.12)
2.image

参考地址:https://react-redux.js.org/api/hooks
希望对大家有所帮助

Antd Pro V4升级到2.6beta 12能正常使用了,但是connect报类型错误了
下面是TableList的错误提示,怎么修复?

作为表达式调用时,无法解析类修饰器的签名。
  不能将类型“ConnectedComponentClass<typeof TableList, Pick<TableListProps, "form" | "wrappedComponentRef">>”分配给类型“typeof TableList”。
    Type 'Component<Pick<TableListProps, "form" | "wrappedComponentRef">, any, any>' is missing the following properties from type 'TableList': columns, handleStandardTableChange, handleFormReset, toggleForm, and 10 more.

@wangzhipeng404 用hooks了就不需要connect组件了

但是pro框架的layout和block有使用conect,我得自己都改掉吗,有没有什么办法可以快速修复这些类型错误

我写了一个简单的测试用例,以下代码是普通方式的写法,可以正常使用

import React, { Component } from 'react';
import { connect } from 'dva';
import ProductList from '../components/ProductList';

@connect(({ products }) => ({
  products,
}))
export default class Products extends Component {
  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'products/fetch',
    });
  }
  handleDelete = id => {
    const { dispatch } = this.props;
    dispatch({
      type: 'products/delete',
      payload: id,
    });
  };
  render() {
    const { products } = this.props;
    return (
      <div>
        <h2>List of Products</h2>
        <ProductList onDelete={this.handleDelete} products={products} />
      </div>
    );
  }
}

后来我参考了 https://react-redux.js.org/next/api/hooks 想改写成 hooks 的方式

import React, { useEffect } from 'react';
// import { connect } from 'dva';
import ProductList from '../components/ProductList';
import { useSelector, useDispatch } from 'react-redux';

// https://react-redux.js.org/next/api/hooks

export default function Products() {
  console.info(`useDispatch: `,useDispatch)
  const dispatch = useDispatch();
  const products = useSelector(state => state.products);
  useEffect(() => {
    dispatch({
      type: 'products/fetch',
    });
  });
  const handleDelete = id => {
    dispatch({
      type: 'products/delete',
      payload: id,
    });
  };
  return (
    <div>
      <h2>List of Products</h2>
      <ProductList onDelete={handleDelete} products={products} />
    </div>
  );
}

但这时候就报错了

image

强烈希望可以支持 hooks

@liudonghua123 提问这点时间不如看一眼dva源代码来的快。你下面的代码不使用dva又不按react-redux的要求提供, 用dva就替你做了这个, 能用才怪。

@liudonghua123 你上方所谓的能用的例子,没有加载dva初始化也不可能能正常使用,dva也不过是直接导出react-redux的connect、useSelector等方法而已。

@yoyo837 我上面可以正常使用的代码是部分代码,dva初始化的部分在其他地方,这里我没有全部写上去,代码是参考 https://dvajs.com/guide/getting-started.html 写的,我刚上传到 github 上了,https://github.com/liudonghua123/dva-quickstart/blob/hooks/src/routes/Products.js , hooks分支是有问题的,master分支是可以正常使用的

我试了以下上面说的更新dva2.6.0-beta.14,代码没有修改是可以正常使用了,不过为了统一,useSelector, useDispatchdva 中导出要好一点
所有修改是
https://github.com/liudonghua123/dva-quickstart/commit/f9bd1dd1332e62739d15050c4d50bc069a7fb58f

但是pro框架的layout和block有使用conect,我得自己都改掉吗,有没有什么办法可以快速修复这些类型错误

你好 这个问题请问你解决了吗?在antd-pro-ts 使用的 dva_beta版本,好像会报错

could not find react-redux context value; please ensure the component is wrapped in a <Provider>

感觉很多东西都封装在里面了

@liudonghua123 你上方所谓的能用的例子,没有加载dva初始化也不可能能正常使用,dva也不过是直接导出react-redux的connect、useSelector等方法而已。

有道理,确实好像不能混着用,不是同个原理

Antd Pro V4升级到2.6beta 12能正常使用了,但是connect报类型错误了
下面是TableList的错误提示,怎么修复?

作为表达式调用时,无法解析类修饰器的签名。
  不能将类型“ConnectedComponentClass<typeof TableList, Pick<TableListProps, "form" | "wrappedComponentRef">>”分配给类型“typeof TableList”。
    Type 'Component<Pick<TableListProps, "form" | "wrappedComponentRef">, any, any>' is missing the following properties from type 'TableList': columns, handleStandardTableChange, handleFormReset, toggleForm, and 10 more.

我也遇到这个问题了 请问你解决了吗

用hook就不需要再用connect噢。

用hook就不需要再用connect噢。

嗯 不过项目之前都是用class组件写的 都用hooks重构工作量有点大 而且这个类型警告看着太闹心了

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings