如何在功能性 React JS 组件中获取数据?
Posted
技术标签:
【中文标题】如何在功能性 React JS 组件中获取数据?【英文标题】:How to fetch data in a functional react JS component? 【发布时间】:2020-08-04 22:27:34 【问题描述】:我正在开发一个 React JS、Redux、GraphQL、TypeScript 应用程序。
我想知道如何调用从我的容器中通过 GraphQL 获取数据和更新状态的函数。
通过 GraphQL 加载数据的动作名称为 appActions.getAppData();
但它会导致无限刷新循环,因为它会触发 (StatusActions.startAppLoading());这也会更新状态。
我想知道如何解决此问题或如何将 /Main/index.tsx 重写为类组件并从 componentDidMount() 调用 startAppLoading()。
提前谢谢你。
main.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import Provider from 'react-redux';
import createBrowserHistory from 'history';
import configureStore from 'app/store';
import Router from 'react-router';
import App from './app';
// prepare store
const history = createBrowserHistory();
const store = configureStore();
ReactDOM.render(
<Provider store=store>
<Router history=history>
<App />
</Router>
</Provider>,
document.getElementById('root')
);
app/index.tsx
import React from 'react';
import Route, Switch, Redirect from 'react-router-dom';
import App as Main from 'app/containers/Main';
import hot from 'react-hot-loader';
let currentContainer = Main;
export const App = hot(module)(() => (
<Switch>
<Route exact path="/" component=currentContainer />
<Route path="*">
<Redirect to="https://google.com" />
</Route>
</Switch>
));
app/containers/Main/index.tsx
import React from 'react';
import style from './style.css';
import RouteComponentProps from 'react-router';
import useDispatch, useSelector from 'react-redux';
import useTodoActions from 'app/actions';
import useAppActions from 'app/actions';
import RootState from 'app/reducers';
import Header, TodoList, Footer from 'app/components';
export namespace App
export interface Props extends RouteComponentProps<void>
export const App = ( history, location : App.Props) =>
const dispatch = useDispatch();
const appActions = useAppActions(dispatch);
const apps = useSelector((state: RootState) =>
return
apps: state.apps
;
);
appActions.getAppData();
return (
<div className=style.normal>
<Header />
<TodoList appActions=appActions apps=apps />
<Footer />
</div>
);
;
app/actions/apps.ts
export const getAppData = () =>
let appKey = 'interpegasus';
return (dispatch: Dispatch) =>
dispatch(StatusActions.startAppLoading());
debugger;
apolloClient
.query(
query: gql`
query getApp($appKey: String!)
getApp(id: $appKey)
id
name
domain
`,
variables:
appKey: appKey
)
.then((result) =>
debugger;
if (result.data.apps.length > 0)
dispatch(populateAppData(result.data.apps[0]));
dispatch(StatusActions.endAppLoading());
)
.catch((error) =>
dispatch(StatusActions.endAppLoading());
console.log(
error: error
);
);
;
;
【问题讨论】:
【参考方案1】:你应该把你的 appActions.getAppData()
放在 useEffect
这样的钩子里
useEffect(()=>
appActions.getAppData()
,[])
查看官方文档Introducing Hooks
【讨论】:
【参考方案2】:在Main/index.tsx
中,您正在调用appActions.getAppData();
,这将引导您到actions/apps.ts
。在这里,您正在执行dispatch(StatusActions.startAppLoading());
,它将更新状态并重新渲染“Main/index.tsx”。然后再次调用 getAppData() 并且循环继续导致无限循环。
只有在不是loading
时才调用api。
类似这样的:
...
const apps, loading = useSelector((state: RootState) =>
return
apps: state.apps,
loading: state.loading // <----- replace with your actual name of your state
;
);
if(!loading)
appActions.getAppData();
...
【讨论】:
以上是关于如何在功能性 React JS 组件中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何将从 API 获取的数据作为道具传递给其路由在 React JS 的另一个页面中定义的组件?
如何在 React 功能组件中获取表单/提交以使用 ReactStrap?
如何在 React 函数组件中不使用 useEffect 钩子获取数据?
如何使用功能方法(即非基于类)在 React js 中制作纯组件