useLocation 无法识别状态

And*_*rón 4 javascript typescript reactjs react-router

我开始使用react-router,我发现我可以在 Link 组件中传递“props”,以便某些值可以传递到另一个组件。我正在使用的按钮内发送一个名为“值”的组件,但是在接收该参数的组件中显示一条错误消息,其中包含消息“对象可能为空或未定义”。

\n\n

这是我的代码:

\n\n

我发送数据的地方:

\n\n
<Container placeholder>\n            <Segment>\n            <Form>\n                <Form.Field>\n                    <label>Correo</label>\n                    <input placeholder=\'Ingresa tu correo\' name=\'nombre\' onChange={actualizarUser}/>\n                </Form.Field>\n                <Form.Field>\n                    <label>Contrase\xc3\xb1a</label>\n                    <input placeholder=\'Ingresa tu contrase\xc3\xb1a\' name=\'password\' onChange={actualizarUser}/>\n                </Form.Field>\n\n                <Link to={{ pathname:\'/init/home\', state:{ value: token } }}> // Here I\'m sending the props to the next component\n                    <Button type=\'submit\'>SubmitNuevo</Button>\n                </Link>\n                <Button type=\'submit\' onClick={sendInfo}>Prueba</Button>\n            </Form>\n            </Segment>\n        </Container>\n
Run Code Online (Sandbox Code Playgroud)\n\n

以及我接收 location.state 的组件

\n\n
const Logged: React.FC<{}> = () => {\n\nconst [open, setOpen] = useState(false);  \nconst location = useLocation(); // Here I\'m using useLocation to capture the props I sent\nconst [token, setToken] = useState(\'\');\n\nuseEffect(() => {\n        console.log(location.state);\n        setToken(location.state.value); // Here is were I\'m getting the error message\n        console.log(token);\n});\n\nconst handleOpen = () => {\n    setOpen(true);\n}\n\nconst handleClose = () => {\n    setOpen(false);\n}\n\nreturn(<div>\n\n    </div>\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还尝试将其作为道具进行管理,但是还有另一个错误表明位置无法识别:

\n\n

这是第二个选项的信息,关于我在哪里使用 Route 和 props 来传递信息

\n\n
function App() {\n  return (\n    <div className="App">\n      <Navbar bg="dark"  variant="dark">\n        <Navbar.Brand href="#home">\n          Micrin\n        </Navbar.Brand>\n    </Navbar>\n    <Router>\n        <Switch>\n          <Route path=\'/login\' component={InicioSesion} />\n          <Route path=\'/register\' component={Registro} />\n          <Route path=\'/recover\' component={RecuperarCuenta}/>\n          <Route path=\'/init/home\' exact component={Logged} />\n          <Route path=\'/init/stock\' exact component={Logged}  />\n          <Route path=\'/init/menu\' exact component={Logged} />\n          <Route path=\'/init/sales\' exact component={Logged} />\n          <Route path=\'/init/market\' exact component={Logged} />\n          <Route path=\'/\' component={MainPage} />\n        </Switch>\n    </Router>\n    </div>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

以及使用我发送的 props 渲染的组件

\n\n
const Logged: React.FC<{}> = (props) => {\n    const [open, setOpen] = useState(false);  \n    const [token, setToken] = useState(\'\');\n\nuseEffect(() => {\n        console.log(props.location.state);\n        setToken(props.location.state.value); // Shows error message \'Property location does not exist on type {children?: ReactNode}\'\n        console.log(token);\n});\n\nconst handleOpen = () => {\n    setOpen(true);\n}\n\nconst handleClose = () => {\n    setOpen(false);\n}\n\nreturn(\n    <div></div>\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

感谢您的帮助

\n

Hug*_*ugo 5

您收到的第二个错误是 Typescript 错误。发生这种情况是因为 Typescript 不知道你的 props 的接口。

当你定义你的组件时,你可以通过编写以下内容来告诉 Typescript 它是一个 React 功能组件:

const Logged: React.FC<{}>
Run Code Online (Sandbox Code Playgroud)

Logged是 类型的变量React.FC。这React.FC是一个泛型类型。这意味着它可以进行争论。这个参数是你的组件接受的 props 类型。

在这里,您告诉 Typescript 您的组件根本不接受任何 props:React.FC< {} >。所以 Typescript 期望Logged成为基本的 React 功能组件(所以它只接受,最终是一些子组件)。

location这就是为什么当你尝试从 props获取时 Typescript 会抱怨: Typescript does not Expect to have such a prop:

在此输入图像描述

您需要告诉 Typescript 该组件接受 location 属性。您可以通过创建如下界面来做到这一点:

interface Props {
  // your props here
  location;
}

const Logged: React.FC<Props> = ({ location }) => {
  // your code
}
Run Code Online (Sandbox Code Playgroud)

(注意:我还使用了 props 解构,因为我认为它使代码更清晰,但可以随意在组件中直接使用 props)

但在这里,我只是告诉 Typescript 有一个location变量,但我没有显式设置它的类型。

就你而言,这有点棘手,因为 React Router 正在为你注入这些道具。因此,在这种情况下,您可以Props像这样扩展您的接口:

import React, { useEffect, useState } from 'react';

import { StaticContext } from 'react-router';
import { RouteComponentProps } from 'react-router-dom';

type LocationState = {
  value: string;
};

interface Props extends RouteComponentProps<{}, StaticContext, LocationState> {
  // Here you can define the other props of your component
  // if needed
}

const Logged: React.FC<Props> = ({ location }) => {
  const [open, setOpen] = useState(false);
  const [token, setToken] = useState('');

  useEffect(() => {
    setToken(location.state.value);
  });

  return <div>Hello</div>;
};

export default Logged;
Run Code Online (Sandbox Code Playgroud)

现在,由于 Typescript 知道您的 props 类型,您的 IDE 也可以自动完成: 在此输入图像描述

它知道value是一个字符串: 在此输入图像描述

我建议你看看这个问题: React Typescript: add location state to React router component

以及一些“TypeScript + React 简介”教程,例如:https: //alligator.io/react/typescript-with-react/

因为你会遇到很多这样的错误,当你知道如何阅读它们时,解决起来并不难。

我认为您的第一个错误也与某些缺失类型有关,但我无法理解您在此处分享的内容的确切问题和原因。