useLocation无法识别状态

时间:2020-05-15 20:51:57

标签: javascript reactjs typescript react-router

我开始使用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>

还有我收到位置信息的组件。

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>
);

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

您遇到的第二个错误是打字稿错误。发生这种情况是因为Typescript无法识别道具的界面。

定义组件时,您可以通过编写以下文字告诉Typescript它是一个React Functional组件:

const Logged: React.FC<{}>

Logged是类型React.FC的变量。 React.FCgeneric类型。这意味着可以接受争论。此参数是组件接受的道具类型。

在这里,您要告诉Typescript您的组件根本不接受任何道具:React.FC << strong> {} >。因此,Typescript希望Logged是基本的React功能组件(因此它仅接受,最终接受一些子项)。

这就是为什么当您尝试从道具中获取location时Typescript会抱怨的原因:Typescript期望没有这样的道具:

enter image description here

您需要告诉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知道道具的类型,因此IDE也可以自动完成: enter image description here

,它知道value是一个字符串: enter image description here

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

以及诸如此类的一些“打字稿入门+反应”教程: https://alligator.io/react/typescript-with-react/

因为这样会导致很多错误,并且当您知道如何阅读它们时,解决起来并不是很难。

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