如何从路由URL获取数据以放入React路由器的回调函数中?

时间:2020-05-02 03:05:39

标签: reactjs router

我正在使用搜索功能。我想在路由中触发一个回调函数,以在数据进入搜索组件之前获取所有数据。

赞:

<Route path="/search/:query" component={QuestionSearchContainer} onChange={()=>store.dispatch(fetchData(query?)) }/>

这是QuestionSearchContainer:

const mapStateToProps = (state,ownProps) => {
    return {
    questions: Object.values(state.entities.questions),
    currentUser: state.entities.users[state.session.id],
    query: ownProps.match.params.query, 
    url: ownProps.match.url 
}}

但是如何获取搜索URL中的查询关键字,以将其作为参数放入我的fetchData中?我想获取数据并将其保存到Redux存储,然后再进入QuestionSearchContainer,以便可以获取容器中所有问题的数据。

2 个答案:

答案 0 :(得分:0)

如果您不想使用QuestionSearchContainer组件进行数据获取,则可以制作一个高阶组件来包装它,以便为您进行数据获取。

您可以轻松地修改此HOC,以便仅在数据加载完成时才返回Wrapped组件。此过程的加载部分假设fetchData是redux thunk动作创建者。 useParams是从react-router-dom导出的钩子,可让您访问match参数。 useDispatch是从react-redux导出的钩子,可让您访问商店的调度功能。

import { useParams } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { useEffect, useState } from 'react';

const withFetchData = (Component) => ({ children, ...props }) => {
  const { query } = useParams();
  const [loading, setLoading] = useState(true);
  const dispatch = useDispatch();
  useEffect(() => {
    // Assuming fetchData is a a redux thunk action creator
    setLoading(true);

    dispatch(fetchData(query)).then(() => {
      setLoading(false);
    });
  }, [query]);
  if(loading){
    return 'loading...'
  }
  return <Component {...props} />;
};
const QuestionSearchContainerWithFetchData = withFetchData(
  QuestionSearchContainer
);

const Parent = () => {
  return (
    <Route
      path="/search/:query"
      component={QuestionSearchContainerWithFetchData}
    />
  );
};

另一个选择是创建一条符合您期望的特殊路线。例如,每次参数更改时,此OnChangeRoute函数将使用当前参数调用回调onChangeParams。在这一本书中,有一个加载道具,您必须传递它,因为组件本身并不关心您对参数所做的事情。

import { useEffect, useRef } from "react";

function InnerOnChangeRoute({ loading, onParamsChange, Component, ...rest }) {
  const onChangeRef = useRef(onParamsChange);
  useEffect(()=>{
    onChangeRef.current=onParamsChange;
  },[onParamsChange])
  useEffect(() => {
    onChangeRef.current(rest.match.params);
  }, [rest.match.params]);
  if(loading){
    return 'loading....'
  }
  return <Component {...rest} />;
}
// A wrapper for <Route> that redirects to the login
// screen if you're not yet authenticated.
function OnChangeRoute({ Component, onParamsChange, loading, ...rest }) {
  return (
    <Route
      {...rest}
      render={(data) => (
        <InnerOnChangeRoute
          Component={Component}
          onParamsChange={onParamsChange}
          loading={loading}
          {...data}
        />
      )}
    />
  );
}

通常,对于redux,您必须使用分派(或连接器HOC中的mapDispatchToProps)来执行操作,以用数据更新商店。

有些链接有望帮助您更好地控制redux。

https://redux.js.org/advanced/async-actions

https://redux-toolkit.js.org/usage/usage-guide#asynchronous-logic-and-data-fetching

https://github.com/reduxjs/redux-thunk

答案 1 :(得分:0)

首先,Route没有onChange处理程序。 ({{1}的早期版本(3及更早版本)提供了onEnter

由于您的需求似乎只针对单个组件(QuestionSearchContainer),因此使用自定义钩子或hoc可能不是理想的解决方案。

您可以简单地使用react-router-dom并监听网址更改(查询)。您可以使用useEffect获取query并将其作为参数传递给调度回调。

只需确保在恢复时保持props.match.params状态,并在获取数据时呈现loading

代码段

fallback