javascript - useLocation não reconhece estado
Comecei a usar react-router e descobri que posso passar 'props' no componente Link para que alguns valores sejam passados para outro componente. Estou enviando um componente chamado 'value' dentro do botão que estou usando, no entanto, no componente que recebe esse parâmetro, aparece uma mensagem de erro com a mensagem 'Object is possibly null or undefined'.
Aqui está meu código:
Para onde estou enviando os dados:
<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>
E o componente onde eu recebo 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>
);
Eu também tentei gerenciar isso como props, no entanto, há outro erro que mostra como se location não fosse reconhecido:
Aqui está a informação da segunda opção sobre onde estou usando Route e props para passar a informação
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>
);
}
E o componente renderizando com as props que eu enviei
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>
);
Obrigado pela sua ajuda
Resposta #1
O segundo erro que você está recebendo é um erro do Typescript. Ele ocorre porque o Typescript não está ciente da interface das suas props.
Quando você define seu componente, você informa ao TypeScript que ele é um componente funcional do React escrevendo:
const Logged: React.FC<{}>
Logged é uma variável do tipo React.FC. O React.FC é um tipo genérico. Isso significa que ele pode receber um argumento. Esse argumento é o tipo de props que seu componente aceita.
Aqui, você está informando ao Typescript que seu componente não aceita props algum: React.FC<{}>. Então o Typescript espera que Logged seja um componente funcional React básico (portanto, ele aceita apenas, eventualmente, alguns children).
É por isso que o Typescript reclama quando você tenta obter location das props: o Typescript não espera ter tal prop:
Você precisa informar ao Typescript que este componente aceita uma prop de localização. Você pode fazer isso criando uma interface assim:
interface Props {
// your props here
location;
}
const Logged: React.FC<Props> = ({ location }) => {
// your code
}
(nota: Eu também usei a desestruturação de props porque acho que deixa o código mais limpo, mas sinta-se à vontade para usar props diretamente no seu componente)
Mas aqui, eu apenas disse ao TypeScript que existe uma variável location, mas não defini explicitamente seu tipo.
No seu caso, é um pouco mais complicado porque o React Router está injetando essas props para você. Então, neste caso, você pode estender sua interface Props assim:
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;
E agora, porque o TypeScript está ciente do tipo das suas props, seu IDE também pode completar automaticamente:
e ele sabe que value é uma string:
Sugiro que você dê uma olhada nesta pergunta do SO: React Typescript: adicionar estado de localização ao componente do react router
e para alguns tutoriais de "introdução ao TypeScript + React" como este: https://alligator.io/react/typescript-with-react/
Porque você vai encontrar muitos erros assim e, quando souber como lê-los, não é muito difícil de resolver.
Acho que seu primeiro erro também está relacionado a alguns tipos ausentes, mas não consegui entender o problema exato e o motivo com o que você compartilhou aqui.


