【问题标题】:useLocation doesn't recognize stateuseLocation 无法识别状态
【发布时间】:2020-09-01 19:19:07
【问题描述】:

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

这是我的代码:

我将数据发送到哪里:

<Container placeholder>
            <Segment>
            <Form>
                <Form.Field>
                    <label>Correo</label>
                    <input placeholder='Ingresa tu correo' name='nombre' onChange={actualizarUser}/>
                </Form.Field>
                <Form.Field>
                    <label>Contraseña</label>
                    <input placeholder='Ingresa tu contraseña' name='password' onChange={actualizarUser}/>
                </Form.Field>

                <Link to={{ pathname:'/init/home', state:{ value: token } }}> // Here I'm sending the props to the next component
                    <Button type='submit'>SubmitNuevo</Button>
                </Link>
                <Button type='submit' onClick={sendInfo}>Prueba</Button>
            </Form>
            </Segment>
        </Container>

以及我收到 location.state 的组件

const Logged: React.FC<{}> = () => {

const [open, setOpen] = useState(false);  
const location = useLocation(); // Here I'm using useLocation to capture the props I sent
const [token, setToken] = useState('');

useEffect(() => {
        console.log(location.state);
        setToken(location.state.value); // Here is were I'm getting the error message
        console.log(token);
});

const handleOpen = () => {
    setOpen(true);
}

const handleClose = () => {
    setOpen(false);
}

return(<div>

    </div>
);

我也尝试将其作为道具进行管理,但是还有另一个错误显示它好像无法识别位置:

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

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

以及我发送的带有道具的组件渲染

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

useEffect(() => {
        console.log(props.location.state);
        setToken(props.location.state.value); // Shows error message 'Property location does not exist on type {children?: ReactNode}'
        console.log(token);
});

const handleOpen = () => {
    setOpen(true);
}

const handleClose = () => {
    setOpen(false);
}

return(
    <div></div>
);

感谢您的帮助

【问题讨论】:

    标签: javascript reactjs typescript react-router


    【解决方案1】:

    您遇到的第二个错误是 Typescript 错误。这是因为 Typescript 不知道你的 props 的接口。

    当你定义你的组件时,你告诉 Typescript 它是一个 React 函数式组件:

    const Logged: React.FC<{}>
    

    LoggedReact.FC 类型的变量。 React.FCgeneric 类型。这意味着它可以接受一个论点。这个参数是你的组件接受的 props 的类型。

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

    这就是当你尝试从 props 中获取 location 时,Typescript 抱怨的原因:Typescript 不希望有这样的 prop:

    你需要告诉 Typescript 这个组件接受一个位置属性。您可以通过创建这样的界面来做到这一点:

    interface Props {
      // your props here
      location;
    }
    
    const Logged: React.FC<Props> = ({ location }) => {
      // your code
    }
    

    (注意:我也使用了 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;
    

    现在,因为 Typescript 知道你的 props 的类型,你的 IDE 也可以自动完成:

    它知道value 是一个字符串:

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

    还有一些“typescript + react 简介”教程,例如: https://alligator.io/react/typescript-with-react/

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-19
      • 2020-12-20
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 2023-01-11
      • 2022-01-21
      • 1970-01-01
      相关资源
      最近更新 更多