如何停止useDispatch()无限调度动作?

背景

我正在使用React-Redux和React Hooks进行项目。

我有一个组件,该组件调度一个动作fetchCollectionData(),该组件首先调度一个动作requestCollectionData(),该动作将reducer的waiting属性更新为true。然后fetchCollectionData()发出超级代理请求,以从服务器获取数据。响应返回后,fetchCollectionData()调度另一个动作receiveCollectionData(),该动作将使用结果更新reducer并将waiting属性设置为false。 API结果将带回的数据向下传递到子组件中的表。

问题:useDispatch()无限循环地调度fetchCollectionData()操作。我只希望在组件安装时将此动作调度一次。

尝试:我曾尝试使用useEffect()钩子useEffect(fetchCollectionData(),[]),但收到一条错误消息,指出useEffect不应用于承诺。

错误文本:

Warning: An effect function must not return anything besides a function,which is used for clean-up.

It looks like you wrote useEffect(async () => ...) or returned a Promise. Instead,write the async function inside your effect and call it immediately:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
},[someId]); // Or [] if effect doesn't need props or state

    in ContainerComponent (created by Context.Consumer)
    in Route (at App.js:35)
    in Switch (at App.js:33)
    in div (at App.js:20)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:19)
    in App (at Root.js:8)
    in Provider (at Root.js:7)
    in Root (at src/index.js:8)

我尝试将操作更改为export async function fetchCollectionData(),但这导致我遇到更多错误。

父组件

export const ContainerComponent = () => {
  const dispatch = useDispatch();
  dispatch(actions.fetchCollectionData());
  const data = useSelector(state => state.accountMaintenanceReducer.result);
  const rows = data ? data : [];
  return (
    <div style={containerStyle}>
      <div classname="section-header">
        <span>account Maintenance</span>
      </div>
      <TableComponent rows={rows} />
    </div>
  );
};

子组件

import React from "react";
import { Table,TableHead,TableBody,TableRow,TableCell } from '@material-ui/core';

const columns = [,{name: 'Primary Owner',key: 'owner'},{name: 'Mailing Address',key: 'address'},];

const dataToRows = (data) => {
  if (data.rows.length) {
    return data.rows.map(row => {
      const index = row.ownerAndAddress.indexOf(String.fromCharCode(13));
      const owner = row.ownerAndAddress.substring(0,index);
      const address = row.ownerAndAddress.substring(index + 2);
      return {
        owner: owner,address: address,}
    });
  }
};

export const TableComponent = (data) => {
  const rows = dataToRows(data);
  return (
    <Table>
      <TableHead>
        <TableRow>
          {columns.map(column => (
            <TableCell key={columns.indexOf(column)}>
              {column.name}
            </TableCell>
          ))}
        </TableRow>
      </TableHead>
      <TableBody>
        { rows ?
          rows.map(row => (
            <TableRow key={rows.indexOf(row)}>
              { Object.keys(row).map(cell => (
                <TableCell classname={cell} key={cell}>
                  {row[cell]}
                </TableCell>
              ))}
            </TableRow>
          )) :
          <TableRow>
            <TableCell>No Data</TableCell>
          </TableRow>
        }
      </TableBody>
    </Table>
  );
};

动作

export function receiveCollectionData(body) {
  return {
    type: 'RECEIVE_COLLECTION_DATA',result: body,}
}

export function requestCollectionData() {
  return {
    type: 'REQUEST_COLLECTION_DATA',}
}

export function fetchCollectionData() {
  return dispatch => {
    dispatch(requestCollectionData());
    return request.get(`api/accounts/getcollectionBySearch?searchString=Smith`)
      .then(res => res.body)
      .then(body=> dispatch(receiveCollectionData(body)))
  }
}

减速器

export default (state = {},action) => {
  switch (action.type) {
    case 'GET_COLLECTION_DATA':
      return {
        ...state,waiting: true
      };
    case 'RECEIVE_COLLECTION_DATA':
      return {
        ...state,result: action.result,waiting: false
      };
    default:
    return state;
  }
}

所需的解决方案

我想做的是模仿componentDidmount()的功能,并在组件安装后分派fetchCollectionData()。似乎fetchCollectionData()一旦解决,就会再次调度,从而导致无限循环。

免责声明

目标是获得一种将React Hooks与Redux结合使用并且不依赖于类组件的解决方案。

shenwenxia715 回答:如何停止useDispatch()无限调度动作?

在父组件上


 const dispatch = useDispatch();
 useEffect(()=> dispatch(actions.fetchCollectionData(),[]);

应该工作。 由于某些原因,当您尝试使用useEffect时,它似乎没有分派

,

已更改:

const dispatch = useDispatch(); useEffect(()=> dispatch(actions.fetchCollectionData(),[]);

收件人:

const dispatch = useDispatch(); useEffect(()=> {dispatch(actions.fetchCollectionData()},[]);

,

对于你们中的那些人,上面的方法并没有解决它,useEffect中的一个简单的if语句可以解决它。就我而言,我的值最初为null,因此我想模仿旧的ComponentDidMount方法。这是简单明了的解决方案。

  useEffect(() => {
        if (yourvalue === null) 
           dispatch(actiontodispatch()); 
        },[]);

关键部分是开头为null / false或其他任何值的值。不过,不确定性能。

本文链接:https://www.f2er.com/3148827.html

大家都在问