通过 useContext 从登录和图像传递图像时不显示
While passing image via useContext from login and image is not displaying
在登录的 onSubmit 期间,我做了 setLoginPhoto(res.data.photo)
然后使用 useContext()
将照片信息传递给 Navigation。但是显然,一旦登录成功并显示主屏幕,照片信息就会被清除。另外 loginPhoto.photo,单独的照片是 undefined
,但我可以在 loginPhoto
中看到图像细节,同时将鼠标悬停在它上面。
点击登录后,我设置了各种断点,看到图像信息实际上传递给UserLoginProvider
,然后在Navigation
中可用。 (请参考截图)
注意:图像文件路径使用 multer 保存到数据库,即 [var imagePath = req.file.path;
] 并且图像显示在其他屏幕中,如主页、个人资料屏幕。
一步一步:
按登录,我可以看到 UserLoginProvider
中的 loginPhoto
有图像(请参考截图)
现在我可以在导航中看到 loginPhoto
:
但是一旦登录成功并显示主页,loginPhoto
变为空并且图像不显示在导航中。关于如何解决此问题的任何建议?
Login.js
import React, { useContext, useEffect, useState } from "react";
import { UserProfileContext, UserLoginContext } from '../context';
const {loginPhoto, setLoginPhoto} = useContext(UserLoginContext);
const [helperText, setHelperText] = useState('');
const [value, setValue] = React.useState('');
const onSubmit = () => {
const fetchData = async () => {
try {
const res = await axios.post('http://localhost:8000/service/login', { email, password });
//setLoginData(res.data.loginData);
console.log("Front End success message:" + res.data.success);
console.log("My Photo Data:" + res.data.photo);
setLoginPhoto(res.data.photo);
if (res.data.success) {
setHelperText("Login successfully");
setValue(res.data.privilege);
localStorage.setItem('Privilege', res.data.privilege);
localStorage.setItem('loginEmail', email);
history.push('/')
window.location.reload(true)
}
else {
const failMessage = res.data.fail;
setHelperText(failMessage);
}
} catch (e) {
console.log(e.response.data);
setHelperText(e.response.data.fail);
}
}
fetchData();
};
UserLoginProvider.js
import { UserProfileContext, UserLoginContext } from '../context';
const UserLoginProvider = ({children}) => {
const [loginPhoto, setLoginPhoto] = useState({ photo: ''});
console.log("Nav Image:"+loginPhoto);
const value = useMemo(() => ({
loginPhoto, setLoginPhoto
}), [loginPhoto]);
return (
<UserLoginContext.Provider value={value}>
{children}
</UserLoginContext.Provider>
)
}
export default UserLoginProvider;
Navigation.js
import { UserProfileContext, UserLoginContext } from '../context';
const { loginPhoto } = useContext(UserLoginContext);
useEffect(() => {
if (loginPhoto.photo) {
const reader = new FileReader();
reader.addEventListener('load', () => {
setImgSrc(reader.result);
localStorage.setItem("imgData", reader.result);
});
reader.readAsDataURL(loginPhoto.photo);
}
}, [loginPhoto.photo])
var loginUserImg = localStorage.getItem('imgData');
console.log(loginUserImg);
<img className="nav_profile" src={loginUserImg}></img>
App.js
var ReactDOM = require("react-dom");
const App = () => {
return (
<BrowserRouter>
<UserLoginProvider>
<UserProfileProvider>
<>
<Navigation />
<Switch>
<ProtectedRoute exact path="/" component={Home} />
<ProtectedRoute path="/profile" component={Profile} />
<ProtectedRoute path="/aboutus" component={Aboutus} />
<ProtectedRoute path="/availability" component={Availability} />
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
<Route exact path="*" component={ErrorPage} />
</Switch>
</>
</UserProfileProvider>
</UserLoginProvider>
</BrowserRouter>
);
};
ReactDOM.render(
React.createElement(App, null),
document.getElementById("root")
);
export default App;
home.js
import React, { useRef, useEffect, useState } from "react";
import AlertDialog from "../modal/Dialog";
import Axios from "axios";
const Home = () => {
const [phoneTooltip, setPhoneTooltip] = useState({ show: false, position: "absolute" });
const [playerList, setPlayerList] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState([]);
const [deleteIcon, setDeleteIcon] = useState({ show: false });
const [deleteDialog, setDeleteDialog] = useState(false);
const [playerId, setPlayerId] = useState("");
const isMounted = useRef(false);
const [isLoading, setIsLoading] = useState(true);
const handleChange = event => {
setSearchTerm(event.target.value);
};
useEffect(() => {
isMounted.current = true;
return () => isMounted.current = false;
}, []);
useEffect(() => {
setTimeout ( () => {
const fetchData = async () => {
try {
const res = await Axios.get('http://localhost:8000/service/players');
if (isMounted.current) {
setPlayerList(res.data.players);
setSearchResults(res.data.players);
const privilege = localStorage.getItem('Privilege');
console.log("What is getting in Front End:" + privilege);
showDeleteIcon(privilege);
setIsLoading(false);
}
} catch (e) {
if (isMounted.current) {
setIsLoading(false);
}
console.log(e);
}
}
fetchData();
}, 1500);
}, []);
useEffect(() => {
const results = playerList.filter(player =>
player.name.toLowerCase().includes(searchTerm) || player.name.toUpperCase().includes(searchTerm) || player.position.toLowerCase().includes(searchTerm)
|| player.position.toUpperCase().includes(searchTerm)
);
setSearchResults(results);
}, [searchTerm, playerList]);
const displayPhoneToolTip = (userId) => e => {
e.preventDefault();
setPhoneTooltip(userId); // show tooltip
setTimeout(() => {
setPhoneTooltip(false); // remove/hide tooltip
}, 4000);
};
const showDeleteIcon = (privilege) => {
if (privilege === "ADMIN") {
setDeleteIcon({ show: true })
} else {
setDeleteIcon({ show: false })
}
}
const deletePlayer = (id) => e => {
setPlayerId(id);
setDeleteDialog(true);
}
const onDelete = id => () => {
try {
Axios.delete('http://localhost:8000/service/player', {
headers: {
'Content-Type': 'application/json'
},
data: {
'id': id
}
});
setDeleteDialog(false);
const restOfPlayerResults = searchResults.filter((result) => result.id !== id)
setSearchResults(restOfPlayerResults);
} catch (e) {
console.log(e);
}
}
return (
<div className="App">
<div className="wrapper">
<div className="playerList_header">
<h2>Players</h2>
<label>
<div className="playerSearch_Home">
<div className="playerSearch_Icon">
<img alt="" src="/images/search-image-player.jpg"></img>
</div>
<input type="text" className="playerSearch_Home_Input" placeholder="Search players..." value={searchTerm} onChange={handleChange} />
</div>
</label>
</div>
<div>
{!searchResults.length && !isLoading && (<div> <p className="noSearchData"> Does not match any results! </p> </div>)}
<div className="playerList_home_page">
{isLoading ? (
<div className="loader">
<div className="bubble"></div>
<div className="bubble"></div>
<div className="bubble"></div>
<div className="bubble"></div>
</div>
) : (
<div className="grid-container">
{
searchResults.map(({ id, photo, position, phonenumber, name }) => (
<div key={id} className="grid-item">
{
deleteIcon.show && (
<span className="deletePlayerButton" onClick={deletePlayer(id)}>
<img className="deletePlayerimg" src="/images/delete.png"></img>
</span>
)}
<div>
<img alt="" className="playerProfilePic_home_tile" key={photo} src={photo}></img>
</div>
<div className="playerProfile_grid_border">
<span className="rec_name_position_data">
<h3 key={name}>{name}</h3>
<span className="playerPosition_home_tile" key={position}>{position}</span>
</span>
</div>
<span className="phoneNumber_home">
<img src="/images/phone.png" alt={"phoneTooltip.show"} key={id} name="phoneNumberhomeicon" onClick={displayPhoneToolTip(id)} />
</span>
{phoneTooltip === id && (
<div className="tooltip_PhoneNumber_home" key={phonenumber}>{phonenumber}</div>
)}
</div>
))
}
</div>
)}
</div>
</div>
</div>
<AlertDialog
onDelete={onDelete}
open={deleteDialog}
onClose={() => setDeleteDialog(false)}
playerId={playerId}
/>
</div>
);
}
export default Home;
我已经创建了一个较小的应用程序示例版本来解决您的问题。据我所知,问题是 loginPhoto
作为字符串而不是 {photo: "image/example.jpeg"}
.
形式的对象传入
另一个问题是 window.location.reload(true)
在推送到 Home
页面后被调用。这消除了上下文。
您可以访问我的 Codesandbox 以查看我所做的确切更改。在此 shell 中填写您的额外登录名,看看现在是否正常。
在登录的 onSubmit 期间,我做了 setLoginPhoto(res.data.photo)
然后使用 useContext()
将照片信息传递给 Navigation。但是显然,一旦登录成功并显示主屏幕,照片信息就会被清除。另外 loginPhoto.photo,单独的照片是 undefined
,但我可以在 loginPhoto
中看到图像细节,同时将鼠标悬停在它上面。
点击登录后,我设置了各种断点,看到图像信息实际上传递给UserLoginProvider
,然后在Navigation
中可用。 (请参考截图)
注意:图像文件路径使用 multer 保存到数据库,即 [var imagePath = req.file.path;
] 并且图像显示在其他屏幕中,如主页、个人资料屏幕。
一步一步:
按登录,我可以看到 UserLoginProvider
中的 loginPhoto
有图像(请参考截图)
现在我可以在导航中看到 loginPhoto
:
但是一旦登录成功并显示主页,loginPhoto
变为空并且图像不显示在导航中。关于如何解决此问题的任何建议?
Login.js
import React, { useContext, useEffect, useState } from "react";
import { UserProfileContext, UserLoginContext } from '../context';
const {loginPhoto, setLoginPhoto} = useContext(UserLoginContext);
const [helperText, setHelperText] = useState('');
const [value, setValue] = React.useState('');
const onSubmit = () => {
const fetchData = async () => {
try {
const res = await axios.post('http://localhost:8000/service/login', { email, password });
//setLoginData(res.data.loginData);
console.log("Front End success message:" + res.data.success);
console.log("My Photo Data:" + res.data.photo);
setLoginPhoto(res.data.photo);
if (res.data.success) {
setHelperText("Login successfully");
setValue(res.data.privilege);
localStorage.setItem('Privilege', res.data.privilege);
localStorage.setItem('loginEmail', email);
history.push('/')
window.location.reload(true)
}
else {
const failMessage = res.data.fail;
setHelperText(failMessage);
}
} catch (e) {
console.log(e.response.data);
setHelperText(e.response.data.fail);
}
}
fetchData();
};
UserLoginProvider.js
import { UserProfileContext, UserLoginContext } from '../context';
const UserLoginProvider = ({children}) => {
const [loginPhoto, setLoginPhoto] = useState({ photo: ''});
console.log("Nav Image:"+loginPhoto);
const value = useMemo(() => ({
loginPhoto, setLoginPhoto
}), [loginPhoto]);
return (
<UserLoginContext.Provider value={value}>
{children}
</UserLoginContext.Provider>
)
}
export default UserLoginProvider;
Navigation.js
import { UserProfileContext, UserLoginContext } from '../context';
const { loginPhoto } = useContext(UserLoginContext);
useEffect(() => {
if (loginPhoto.photo) {
const reader = new FileReader();
reader.addEventListener('load', () => {
setImgSrc(reader.result);
localStorage.setItem("imgData", reader.result);
});
reader.readAsDataURL(loginPhoto.photo);
}
}, [loginPhoto.photo])
var loginUserImg = localStorage.getItem('imgData');
console.log(loginUserImg);
<img className="nav_profile" src={loginUserImg}></img>
App.js
var ReactDOM = require("react-dom");
const App = () => {
return (
<BrowserRouter>
<UserLoginProvider>
<UserProfileProvider>
<>
<Navigation />
<Switch>
<ProtectedRoute exact path="/" component={Home} />
<ProtectedRoute path="/profile" component={Profile} />
<ProtectedRoute path="/aboutus" component={Aboutus} />
<ProtectedRoute path="/availability" component={Availability} />
<Route path="/register" component={Register} />
<Route path="/login" component={Login} />
<Route exact path="*" component={ErrorPage} />
</Switch>
</>
</UserProfileProvider>
</UserLoginProvider>
</BrowserRouter>
);
};
ReactDOM.render(
React.createElement(App, null),
document.getElementById("root")
);
export default App;
home.js
import React, { useRef, useEffect, useState } from "react";
import AlertDialog from "../modal/Dialog";
import Axios from "axios";
const Home = () => {
const [phoneTooltip, setPhoneTooltip] = useState({ show: false, position: "absolute" });
const [playerList, setPlayerList] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState([]);
const [deleteIcon, setDeleteIcon] = useState({ show: false });
const [deleteDialog, setDeleteDialog] = useState(false);
const [playerId, setPlayerId] = useState("");
const isMounted = useRef(false);
const [isLoading, setIsLoading] = useState(true);
const handleChange = event => {
setSearchTerm(event.target.value);
};
useEffect(() => {
isMounted.current = true;
return () => isMounted.current = false;
}, []);
useEffect(() => {
setTimeout ( () => {
const fetchData = async () => {
try {
const res = await Axios.get('http://localhost:8000/service/players');
if (isMounted.current) {
setPlayerList(res.data.players);
setSearchResults(res.data.players);
const privilege = localStorage.getItem('Privilege');
console.log("What is getting in Front End:" + privilege);
showDeleteIcon(privilege);
setIsLoading(false);
}
} catch (e) {
if (isMounted.current) {
setIsLoading(false);
}
console.log(e);
}
}
fetchData();
}, 1500);
}, []);
useEffect(() => {
const results = playerList.filter(player =>
player.name.toLowerCase().includes(searchTerm) || player.name.toUpperCase().includes(searchTerm) || player.position.toLowerCase().includes(searchTerm)
|| player.position.toUpperCase().includes(searchTerm)
);
setSearchResults(results);
}, [searchTerm, playerList]);
const displayPhoneToolTip = (userId) => e => {
e.preventDefault();
setPhoneTooltip(userId); // show tooltip
setTimeout(() => {
setPhoneTooltip(false); // remove/hide tooltip
}, 4000);
};
const showDeleteIcon = (privilege) => {
if (privilege === "ADMIN") {
setDeleteIcon({ show: true })
} else {
setDeleteIcon({ show: false })
}
}
const deletePlayer = (id) => e => {
setPlayerId(id);
setDeleteDialog(true);
}
const onDelete = id => () => {
try {
Axios.delete('http://localhost:8000/service/player', {
headers: {
'Content-Type': 'application/json'
},
data: {
'id': id
}
});
setDeleteDialog(false);
const restOfPlayerResults = searchResults.filter((result) => result.id !== id)
setSearchResults(restOfPlayerResults);
} catch (e) {
console.log(e);
}
}
return (
<div className="App">
<div className="wrapper">
<div className="playerList_header">
<h2>Players</h2>
<label>
<div className="playerSearch_Home">
<div className="playerSearch_Icon">
<img alt="" src="/images/search-image-player.jpg"></img>
</div>
<input type="text" className="playerSearch_Home_Input" placeholder="Search players..." value={searchTerm} onChange={handleChange} />
</div>
</label>
</div>
<div>
{!searchResults.length && !isLoading && (<div> <p className="noSearchData"> Does not match any results! </p> </div>)}
<div className="playerList_home_page">
{isLoading ? (
<div className="loader">
<div className="bubble"></div>
<div className="bubble"></div>
<div className="bubble"></div>
<div className="bubble"></div>
</div>
) : (
<div className="grid-container">
{
searchResults.map(({ id, photo, position, phonenumber, name }) => (
<div key={id} className="grid-item">
{
deleteIcon.show && (
<span className="deletePlayerButton" onClick={deletePlayer(id)}>
<img className="deletePlayerimg" src="/images/delete.png"></img>
</span>
)}
<div>
<img alt="" className="playerProfilePic_home_tile" key={photo} src={photo}></img>
</div>
<div className="playerProfile_grid_border">
<span className="rec_name_position_data">
<h3 key={name}>{name}</h3>
<span className="playerPosition_home_tile" key={position}>{position}</span>
</span>
</div>
<span className="phoneNumber_home">
<img src="/images/phone.png" alt={"phoneTooltip.show"} key={id} name="phoneNumberhomeicon" onClick={displayPhoneToolTip(id)} />
</span>
{phoneTooltip === id && (
<div className="tooltip_PhoneNumber_home" key={phonenumber}>{phonenumber}</div>
)}
</div>
))
}
</div>
)}
</div>
</div>
</div>
<AlertDialog
onDelete={onDelete}
open={deleteDialog}
onClose={() => setDeleteDialog(false)}
playerId={playerId}
/>
</div>
);
}
export default Home;
我已经创建了一个较小的应用程序示例版本来解决您的问题。据我所知,问题是 loginPhoto
作为字符串而不是 {photo: "image/example.jpeg"}
.
另一个问题是 window.location.reload(true)
在推送到 Home
页面后被调用。这消除了上下文。
您可以访问我的 Codesandbox 以查看我所做的确切更改。在此 shell 中填写您的额外登录名,看看现在是否正常。