如何在 React hooks 和 redux 中只获取一次且不再获取数据

Posted

技术标签:

【中文标题】如何在 React hooks 和 redux 中只获取一次且不再获取数据【英文标题】:How to fetch data only once and never again in reacthooks and redux 【发布时间】:2021-09-15 16:10:41 【问题描述】:

请问,在使用 React Hooks 在 React 组件中来回移动时,我如何只获取一次数据并且不再获取数据。我只是希望它以这样一种方式,即一旦在组件中第一次获取数据,它就不应该再次获取。在反应钩子中使用空数组 [ ] 将使组件在每次我们再次移动到组件时获取一次数据。 这是 reacthook 中使用的示例代码,仅获取一次数据。 即使从页面/组件转换到组件时,我也只想获取一次数据,而不是再次获取数据。 这两个链接在页面之间导航时仅获取一次数据。谢谢并希望收到大家的来信 http://www.favesound.de/ http://soundredux.io/

useEffect(() => 
const fetchData = async () => 
const result = await axios(url);
setData(result.data);
;
fetchData();
, [url]);

【问题讨论】:

【参考方案1】:

redux 存储数据设置为null 或某个空值。 在发出请求之前,请检查您存储的是否已有数据。 这将确保只有一个请求。

import React from "react";
import  useDispatch, useSelector  from "react-redux";

const Component = () => 
  const dispatch = useDispatch();
  const data = useSelector((state) => state.data);
;

useEffect(() => 
  if (data === null) 
    const fetchData = async () => 
      const result = await axios(url);
      dispatch( type: "update-data", payload: result.data );
    ;
    fetchData();
  
, [data]);

【讨论】:

【参考方案2】:

您可以将结果保存到组件之外的变量中:

let DATA;

function App() 
  const [data, setData] = useState(DATA)

  useEffect(() => 
    if (DATA !== undefined) 
      return;
    

    (async () => 
      const result = await axios(url);
      DATA = result.data;
      setData(DATA);
    )();
  , []);

  ....


我在您的代码中没有看到与 redux 有任何关系。如果你使用 redux,你可以在组件之外获取数据(例如在你创建 store 的文件中),然后调度一个包含获取数据的操作,因此数据只会被获取一次。

const store = createStore(...)

(async () => 
   const result = await axios(url);
   store.dispatch( type: 'INIT_DATA_FETCHED', payload: result.data );
)();

【讨论】:

【参考方案3】:

如果我理解正确,您希望 useEffect 回调仅在第一次渲染时触发一次。

要实现该行为,您可以将一个空数组传递给 useEffect() 的第二个参数,如下所示:

const fetchData = async () => 
const result = await axios(url);
setData(result.data);
;
fetchData();
, []); /* <-- do this */```

【讨论】:

感谢您的回复。使用您提供的代码,fetchData() 只会在组件加载时获取一次,但如果我转到另一个页面/组件,它仍会再次运行 fetchData()。这是我不想要的,因为它是第一次获取。即使我在组件之间来回走动,我也只想获取一次,再也不获取【参考方案4】:

我遇到了同样的问题:当我将操作发送到显示待办事项的“待办事项”组件时。当我在另一个“AddTodos”组件中上传状态下的待办事项时,“Todos”组件没有更新,因为在“Todos”中dispatch(fetchData()); 已从 API 更新状态。

待办事项组件:

useEffect(() => 
 dispatch(fetchData());
, []);

相反,您需要尝试将顶层的 fetchData() 分派到 index.js

store.dispatch(fetchData());

喜欢:

Index.js

const store = createStore(
    rootReducer,
    compose(
        applyMiddleware(thunk),
        /* preloadedState, */
        window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    )
);
store.dispatch(fetchData());

ReactDOM.render(
    <React.StrictMode>
        <Provider store=store>
            <Router>
                <App />
            </Router>
        </Provider>
    </React.StrictMode>,
    document.getElementById('root')
);

这里有解释,并有一个例子。 https://redux.js.org/tutorials/fundamentals/part-6-async-logic#fetching-todos-from-a-server

【讨论】:

以上是关于如何在 React hooks 和 redux 中只获取一次且不再获取数据的主要内容,如果未能解决你的问题,请参考以下文章

React Hooks 与 React-redux

如何修复 React Redux 和 React Hook useEffect 缺少依赖项:'dispatch'

React - Redux Hooks的使用细节详解

如何将 redux-sagas 与 react-hooks 一起使用

等待带有 React Hooks 的 Redux Action

使用 Redux 在 React Hooks 应用程序中添加 Storybook 旋钮