javascript - 异步请求后如何在路由中重定向?

标签 javascript reactjs react-router react-router-dom

我有这段代码,其中我使用 react-router-dom v6 进行路由

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      accounts: [],
    };
  }

  componentDidMount() {
    getAccounts().then(r => this.setState({ // async req
      accounts: r
    }));
  };

  render() {
    return (
      <Routes>
        <Route path="/" element={<AppLayout accounts={this.state.accounts} />}>
          <Route index element={<Navigate to={`/account/1`} />}/>
          <Route path="/account/:accountId" element={<TimelinePage/>}/>
          <Route path="*" element={<NotFoundPage/>}/>
        </Route>
      </Routes>
    );
  }
}

我想从主页重定向到/accounts/${this.state.accounts[0]}但是数组 this.state.accounts在安装 App 组件之前在异步请求之后填充,结果是我第一次呈现时,我到达了 <NotFoundPage/> .这是合乎逻辑的,但我如何才能先获取异步数据,然后才重定向?

我做了一个临时解决方案

<Route index element={<Navigate to={'/account/1'} />}/>`

但这并不能保证ID为1的元素一直存在于数组中


P.S. 数组 this.state.accounts包含具有数字属性 accountId 的对象. <TimelinePage/>里面我使用的组件 useParams()获取帐户 ID 并在 <AppLayout/> 中组件我渲染数组的每个元素

最佳答案

使用 useNavigate Hook 访问 navigate 函数并在获取帐户后发出命令式重定向。这里的问题是 App 是一个类组件,不能直接使用 React hooks。

选项是:

  1. App 转换为功能组件。
  2. 创建自定义 withRouter HOC 以访问 Hook 并将 navigate 作为 prop 注入(inject)。

App 非常简单,可以轻松转换为函数组件。

import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

const App = () => {
  const navigate = useNavigate();
  const [accounts, setAccounts] = useState([]);

  useEffect(() => {
    getAccounts()
      .then(accounts => {
        setAccounts(accounts);
        navigate("/account/1", { replace: true });
      });
  }, []);

  return (
    <Routes>
      <Route path="/" element={<AppLayout accounts={accounts} />}>
        <Route path="/account/:accountId" element={<TimelinePage />} />
        <Route path="*" element={<NotFoundPage />} />
      </Route>
    </Routes>
  );
}

如果类组件更复杂,创建自定义 withRouter HOC 并将 navigate 作为 prop 传递可能会更容易。

import { useNavigate, ...other hooks... } from 'react-router-dom';

const withRouter = Component => props => {
  const navigate = useNavigate();
  ...other hooks...

  return (
    <Component
      {...props}
      navigate={navigate}
      ...other hooks...
    />
  );
};

应用

class App extends Component {
  state = {
    accounts: [],
  }

  componentDidMount() {
    const { navigate } = this.props;
    getAccounts()
      .then(accounts => {
        this.setState({ accounts });
        navigate("/account/1", { replace: true });
      });
  }

  render() {
    const { accounts } = this.state;
    return (
      <Routes>
        <Route path="/" element={<AppLayout accounts={accounts} />}>
          <Route path="/account/:accountId" element={<TimelinePage />} />
          <Route path="*" element={<NotFoundPage />} />
        </Route>
      </Routes>
    );
  }
}

export default withRouter(App);

关于javascript - 异步请求后如何在路由中重定向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71976758/

相关文章:

javascript - React中异步anchor的onClick事件

reactjs - react 警告 : Failed Context Types: Required context `router` was not specified in `Component`

javascript - 一个 Next.js 路由中的两个不同子域

javascript - 如何从文本渲染react-router Link组件?

javascript - 将输入文本拆分为单独的字段

javascript - Leaflet将网格层放在GeJson LayerGroup之上

javascript - Lockfile解释,每一行到底是什么意思? yarn 锁

javascript - 无法使用 ng-changeto 调用功能

javascript - 了解 this 在类方法中的使用

jquery - <svg> 掩码在用于在 react.js 中显示 svg <image> 时不起作用