如何使用 React 从 url 获取参数?

时间:2021-06-19 00:07:02

标签: reactjs react-router react-router-dom

我正在尝试使用 react 设置验证帐户,并在我的 App.js 文件中包含以下内容

<块引用>

App.js

import SigninPage from './pages/signin';
import ResetPasswordPage from './pages/resetPassword'
import VerifyAccountPage from './pages/verifyAccount'
...
...
import { useHistory } from 'react-router';
import { logout } from './utils/auth';

function App() {

  const history = useHistory();
  
  return (
    <Router>
      <Switch>
        <Route path='/' component={Home} exact />
        <Route
            path="/signout"
            render={() => {
              logout();
              history.push('/');
              return null;
            }}
        />
        <Route path='/signin' component={SigninPage} exact />
        <Route path='/reset-password?reset-password-token=:resetPasswordToken' component={ResetPasswordPage} />
        <Route path='/verify-account?token=:token&email=:email' component={VerifyAccountPage} exact />
      </Switch>
    </Router>
  );
}

export default App;

并且在我的 VerifyAccountPage 组件中具有以下内容

import { Redirect } from 'react-router-dom';
import { useHistory } from 'react-router';
import { verifyAccount, isAuthenticated } from '../../utils/auth';


const VerifyAccount = () => {

  const { token, email } = this.props.match.params
  const history = useHistory();
  const [error, setError] = useState('');

  const handleGet = async (e) => {
    e.preventDefault();
    setError('');
    try {
      const data = await verifyAccount(token, email);

      if (data) {
        history.push('/');
      }
      console.log(data);
    } catch (err) {
      if (err instanceof Error) {
        // handle errors thrown from frontend
        setError(err.message);
      } else {
        // handle errors thrown from backend
        setError(err);
      }
    }
  };

  return isAuthenticated() ? (
    <Redirect to="/#" />
    ) : (  
    <>
      <Container>
        <FormWrap>
          <Icon to='/'>mywebsite</Icon>
          <FormContent>
            <Form action='#'>
              <FormH1>Verify Account</FormH1>
              <Text>Account has been verified!</Text>
            </Form>
          </FormContent>
        </FormWrap>
      </Container>
    </>
  );
};

export default VerifyAccount;

这里是 verifyAccount.js

import React from 'react';
import VerifyAccount from '../components/VerifyAccount';
import ScrollToTop from '../components/ScrollToTop';

function VerifyAccountPage() {
  return (
    <>
      <ScrollToTop />
      <VerifyAccount />
    </>
  );
}

export default VerifyAccountPage;

这里

<块引用>

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

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

但这不起作用,当我转到链接 https://mywebsite.com/verify-account?token=3heubek&email=user1@email.com 时,除了 200 或 304 状态代码之外什么都没有发生

没有请求被发送到 API,这意味着参数不会被拉出

谁能告诉我这是怎么回事?

从 package.json 文件中使用的包版本

  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-icons": "^3.11.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.3",
    "react-scroll": "^1.8.1",
    "styled-components": "^5.2.0",
    "@types/node": "^15.6.0",
    "jwt-decode": "^3.0.0"

2 个答案:

答案 0 :(得分:2)

您可以使用 withRouter 获取路由器信息,例如位置、历史记录、路径和参数。

import { withRouter } from "react-router-dom";

...

const VerifyAccount = withRouter(props) => {
  const { token, email } = props.match.params;
  console.log("toke, email: ", token, email)     // And also show me how it looks!!!
  ...
}

你应该像这样定义你的路线。

<Route path='/verify-account/:token/:email' component={VerifyAccountPage} />

你应该这样调用:

https://your-domain/verify-account/[token]/[email]

这会奏效。

答案 1 :(得分:2)

路由匹配参数与 URL 查询字符串参数不同。

您需要从 location 对象访问查询字符串。

<块引用>
{
  key: 'ac3df4', // not with HashHistory!
  pathname: '/somewhere',
  search: '?some=search-string', <-- query string
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}

React-router-dom query parameters demo

他们创建了一个自定义的 useQuery 钩子:

const useQuery = () => new URLSearchParams(useLocation().search);

对于您的用例,在呈现 VerifyAccountPage 的页面上,您要提取查询字符串参数。鉴于path='/verify-account?token=:token&email=:email'

const query = useQuery();

const email = query.get('email');
const token = query.get('token');

基于类的组件?

如果 VerifyAccountPage 是基于类的组件,那么您将需要访问 props.location 并在生命周期方法中自己处理查询字符串。这是因为 React 钩子只被功能组件有效使用。

componentDidMount() {
  const { location } = this.props;
  const query = new URLSearchParams(location.search);
  
  const email = query.get('email');
  const token = query.get('token');
  ...
}

关于路径的注意事项

path='/verify-account?token=:token&email=:email'

路径参数仅与 URL 的路径部分相关,您不能为 URL 的 queryString 部分定义参数。从path='/verify-account'的角度来看,上述路径等效于react-router-dom