我想导航到一个页面/组件,我从另一个组件使用React钩子和useHistory传递数据,但我得到未定义



我是新反应到目前为止3周。登录到我的虚拟应用程序后,我从数据库(useEffect)获取用户作为一个按钮。我想点击一个特定的用户,并在下一页访问他/她的数据。因此,我使用上下文API和useHistory分别将所选用户的数据(状态)发送给组件,并使用history导航到该组件。然而,当路由到该组件时,我收到的是未定义的数据,因为我让该组件可以访问。

import React, { useState, useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import axios from 'axios';
import { useToken } from '../auth/useToken';
import { useUser } from '../auth/useUser';
import { ClassDetails } from './ClassPages/ClassDetails';
export const classSelectedContext = React.createContext();

export const ClassSelection = () => {

const user = useUser();
const [token, setToken] = useToken();
const [classesList, setClassesList] = useState([]);
const [selectedClass, setSelectedClass] = useState('');
const [className, setClassName] = useState('');
const [startDate, setStartDate] = useState('');
const [endDate, setEndDate] = useState('');

const history = useHistory();

const authStr = 'Bearer '.concat(token); 

useEffect( () =>{
axios.get('http://localhost:8081/user/instructor-classes',  {
headers: {
'Authorization': authStr
}
})
.then (res => {
setClassesList(res.data);
})
.catch(
err =>{
console.log(err);
history.push("/")
}
);

},[selectedClass]);

const AddNewClassClicked = () => {
axios.post('http://localhost:8081/user/class', {
className: className,
startDate: startDate,
endDate: endDate,
}, {
headers : {
'Authorization': authStr,
'Content-Type': 'application/json',
}
} )
.then(
//window.location.reload()
)
.catch(err => {
console.log(err)
});
}

const onSelectedClassClicked = () =>{
{history.push('class-detail')} 
}


return (
<div className="content-container">
<div className="content-container">

<h1>Your current classes</h1>
{classesList.map(item => (
<button 
value={item.classIdentifier}
onClick={(e) => {
setSelectedClass(e.target.value)
onSelectedClassClicked()
}}>
{item.className}
</button>

)) } 
<classSelectedContext.Provider value={selectedClass} >
<ClassDetails />
</classSelectedContext.Provider>

</div>

<div className="content-container">
<h1>Add a new Class</h1>
<input
value={className}
onChange={e => setClassName(e.target.value)}
placeholder="Class Name" />
<input
value={startDate}
onChange={e => setStartDate(e.target.value)}
placeholder="Start Date of the Class" /> 
<input
value={endDate}
onChange={e => setEndDate(e.target.value)}
placeholder="End Date of the Class" />               

<button
disabled={
!className || !startDate ||
!endDate 
}
onClick={AddNewClassClicked}>add new Class</button>
</div>
</div>
)

}

所以,在点击按钮之后,我使用历史记录来获取ClassDetails (class-detail),在那里我可以通过useEffect钩子获得传递给该组件的数据。

import React from 'react';
import { useState, useEffect, useContext } from 'react';
import { classSelectedContext } from '../ClassSelection';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
import { useToken } from '../../auth/useToken';
export const ClassDetails = () => {

const [token, setToken] = useToken();

const history = useHistory();
const authStr = 'Bearer '.concat(token); 
let context = useContext(classSelectedContext);


useEffect( () =>{
console.log(context)

axios.get(`http://localhost:8081/user/class/${context}`,  {
headers: {
'Authorization': authStr
}
})
.then (res => {  
console.log(res.data);
})
.catch(
err =>{
console.log(err);
console.log("An error happenned")
}
);
}, []);

return (
<div>
welcome {context}
<div>
{ GetClassDetail(context) }
</div>
{/* <classSelectedContext.Consumer>
{

variable => { GetClassDetail(variable)}
}
</classSelectedContext.Consumer> */}
</div>
)
}

最后,这些是我的路线

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { LogInPage } from './pages/LogInPage';
import { SignUpPage } from './pages/SignUpPage';
import { UserInfoPage } from './pages/UserInfoPage';
import { PrivateRoute } from './auth/PrivateRoute';
import { ClassSelection } from './pages/ClassSelection';
import { WelcomePage } from './pages/WelcomePage';
import { UserLogIn } from './pages/UserLogIn';
import { ClassDetails } from './pages/ClassPages/ClassDetails';
export const Routes = () => {
return (
<Router>
<Switch>
<PrivateRoute path="/class-detail" exact>
<ClassDetails />
</PrivateRoute> 
<PrivateRoute path="/instructor-classes" exact>
<ClassSelection />
</PrivateRoute>
<PrivateRoute path="/select-school" exact>
<UserInfoPage />
</PrivateRoute>
<Route path="/user-login">
<UserLogIn />
</Route>
<Route path="/teacher-login">
<LogInPage />
</Route>
<Route path="/">
<WelcomePage />
</Route>                
<Route path="/signup">
<SignUpPage />
</Route>
</Switch>
</Router>
);
}

请查看codesandbox链接中的代码。我已经尝试创建一个小的应用程序,你正试图使。我已经为路由器添加了一个上下文包装器,这样它就可以在路由更改时使用。你也可以使用render prop,并像下面的代码那样添加带有单独组件的provider。

<Route path="/" render={(props) => (<ContextB><Component2 {...props}/></ContextB>)}/>

也只有当组件被包裹在里面时,历史记录才会起作用反应路由器dom"在你的代码中,你可能正在处理。

棒极了。我需要向useHistory钩子传递不止一个参数,并使用uslocation获取参数,如下所示:

history.push({
pathname: "/class-detail",
search: "?id=someId",
hash: "#someHash",
state: { someState}
})

,那么我可以在你希望使用状态的组件中使用useLocation钩子:

let context = useLocation(history.state);
console.log(context) //this will give you a Json of the history you pushed.

一个想法-您没有在axios调用的按钮点击中包含async/await。可能onSelectedClassClicked运行,在axios调用返回任何数据之前将您推送到类详细信息组件,因此您的classDetails将保持未定义?

它看起来像你错过了一组括号周围的AddNewClassClicked块,它看起来像onSelectedClassClicked是在该函数。

相关内容

  • 没有找到相关文章

最新更新