如何使用 React.js 获取 GET 请求正文中的图像 link?
How can I obtain an image link that is in the body of my GET request using React.js?
我正在使用 spring 引导后端和 react.js 前端作为 Web 应用程序。用户登录后,它会将用户定向到他们的 Profile
,在那里他们将在屏幕上显示他们的用户名、个人资料图片和横幅。我开发了一个后端服务,returns 我在 Postman 上的 GET 请求正文中的必要信息,例如图像(个人资料或横幅)的 link。如果值为 null,我如何使用 React 在 profile_img_complete
中获取必要的 link 并将其插入到我已经有默认图像的图像中?我的演示用户在数据库中有一个图像可以使用,所以它不应该显示默认图像,但它是。任何帮助将不胜感激,这是邮递员信息的图片。
Profile.jsx:
import React, {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import {useSelector} from 'react-redux';
import UserProfileService from '../../services/user-profile.service';
import './styles/Profile.css';
const Profile = () => {
const {user: currentUser} = useSelector((state) => state.auth);
const {id: currentId} = useSelector((state) => state.auth);
const [content, setContent] = useState('');
const [photoURL, setPhotoURL] = useState('../../images/user-solid.svg');
//user-solid is the default image I want if the profile image link is null
useEffect(() => {
UserProfileService.getProfile().then(
(response) => {
setContent(response.data);
},
(error) => {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setContent(_content);
}
);
if (currentId && currentId.profile_img_complete) {
setPhotoURL(currentId.profile_img_complete);
}
}, [currentId]);
if (!currentUser) {
return <Link to='/login' />;
}
return (
<div className='page'>
<div className='profile-container'>
<header className='jumbotron'>
<h3>
<strong id='profile-name'>{currentUser.username}</strong> Profile
</h3>
</header>
<p>
<img src={photoURL} alt='Avatar' className='avatar'></img>
<strong>Token:</strong> {currentUser.accessToken.substring(0, 20)} ...{' '}
{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
</p>
<p>
<strong>Id:</strong> {currentUser.id}
</p>
<p>
<strong>Email:</strong> {currentUser.email}
</p>
<strong>Authorities:</strong>
<ul>
{currentUser.roles &&
currentUser.roles.map((role, index) => <li key={index}>{role}</li>)}
</ul>
<button>
<Link to={'/profile/edit'}>Edit Profile</Link>
</button>
</div>
</div>
);
};
export default Profile;
auth.js:
// We’re gonna import AuthService to make asynchronous HTTP requests with trigger one or more dispatch in the result.
// – register(): calls the AuthService.register(username, email, password) & dispatch setMessage if successful/failed
// – login(): calls the AuthService.login(username, password) & dispatch setMessage if successful/failed
// – logout(): calls the AuthService.logout().
// setMessage is imported from message slice that we’ve created above.
// We also need to use Redux Toolkit createAsyncThunk which provides a thunk that will take care of the action types and dispatching the right actions based on the returned promise.
//There are 3 async Thunks to be exported:
// register
// login
// logout
import {createSlice, createAsyncThunk} from '@reduxjs/toolkit';
import {setMessage} from './messages';
import AuthService from '../services/auth.service';
const user = JSON.parse(localStorage.getItem('user'));
export const register = createAsyncThunk(
'auth/register',
async ({username, email, password}, thunkAPI) => {
try {
const response = await AuthService.register(username, email, password);
thunkAPI.dispatch(setMessage(response.data.message));
return response.data;
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
thunkAPI.dispatch(setMessage(message));
return thunkAPI.rejectWithValue();
}
}
);
export const login = createAsyncThunk(
'auth/login',
async ({username, password}, thunkAPI) => {
try {
const data = await AuthService.login(username, password);
return {user: data};
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
thunkAPI.dispatch(setMessage(message));
return thunkAPI.rejectWithValue();
}
}
);
export const logout = createAsyncThunk('auth/logout', async () => {
await AuthService.logout();
});
const initialState = user
? {isLoggedIn: true, user}
: {isLoggedIn: false, user: null};
const authSlice = createSlice({
name: 'auth',
initialState,
extraReducers: {
[register.fulfilled]: (state, action) => {
state.isLoggedIn = false;
},
[register.rejected]: (state, action) => {
state.isLoggedIn = false;
},
[login.fulfilled]: (state, action) => {
state.isLoggedIn = true;
state.user = action.payload.user;
},
[login.rejected]: (state, action) => {
state.isLoggedIn = false;
state.user = null;
},
[logout.fulfilled]: (state, action) => {
state.isLoggedIn = false;
state.user = null;
},
},
});
const {reducer} = authSlice;
export default reducer;
用户-profile.service.js:
import axios from 'axios';
import authHeader from './auth-header';
const API_URL = 'http://localhost:8080/';
const getProfile = () => {
return axios.get(API_URL + 'profile', {headers: authHeader()});
};
const user_profile = {
getProfile,
};
export default user_profile;
const image = req.query.profile_img
或 const {profile_img} = req.query
我假设图像中的数据是 UserProfileService.getProfile()
返回的 response.data
的值。当 UserProfileService.getProfile()
请求完成时,您需要更新 photoURL。此外,currentId 是一个字符串。它不包含 profile_img_complete
属性。
import React, {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import {useSelector} from 'react-redux';
import UserProfileService from '../../services/user-profile.service';
import './styles/Profile.css';
const Profile = () => {
const {user: currentUser} = useSelector((state) => state.auth);
const {id: currentId} = useSelector((state) => state.auth);
const [content, setContent] = useState('');
const [photoURL, setPhotoURL] = useState('../../images/user-solid.svg');
//user-solid is the default image I want if the profile image link is null
useEffect(() => {
UserProfileService.getProfile().then(
(response) => {
setContent(response.data);
if (response.data.profile_img_complete)
setPhotoURL(response.data.profile_img_complete);
},
(error) => {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setContent(_content);
}
);
}, [currentId]);
if (!currentUser) {
return <Link to='/login' />;
}
return (
<div className='page'>
<div className='profile-container'>
<header className='jumbotron'>
<h3>
<strong id='profile-name'>{currentUser.username}</strong> Profile
</h3>
</header>
<p>
<img src={photoURL} alt='Avatar' className='avatar'></img>
<strong>Token:</strong> {currentUser.accessToken.substring(0, 20)} ...{' '}
{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
</p>
<p>
<strong>Id:</strong> {currentUser.id}
</p>
<p>
<strong>Email:</strong> {currentUser.email}
</p>
<strong>Authorities:</strong>
<ul>
{currentUser.roles &&
currentUser.roles.map((role, index) => <li key={index}>{role}</li>)}
</ul>
<button>
<Link to={'/profile/edit'}>Edit Profile</Link>
</button>
</div>
</div>
);
};
export default Profile;
备用解决方案
state.auth
应该已经持有 profile_img_complete
。所以,你也可以这样做
import React, {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import {useSelector} from 'react-redux';
import UserProfileService from '../../services/user-profile.service';
import './styles/Profile.css';
const Profile = () => {
const {user: currentUser} = useSelector((state) => state.auth);
const auth = useSelector((state) => state.auth);
const {id: currentId} = useSelector((state) => state.auth);
const [content, setContent] = useState('');
const [photoURL, setPhotoURL] = useState(auth.profile_img_complete || '../../images/user-solid.svg');
//user-solid is the default image I want if the profile image link is null
useEffect(() => {
UserProfileService.getProfile().then(
(response) => {
setContent(response.data);
if (response.data.profile_img_complete)
setPhotoURL(response.data.profile_img_complete);
},
(error) => {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setContent(_content);
}
);
}, [currentId]);
if (!currentUser) {
return <Link to='/login' />;
}
return (
<div className='page'>
<div className='profile-container'>
<header className='jumbotron'>
<h3>
<strong id='profile-name'>{currentUser.username}</strong> Profile
</h3>
</header>
<p>
<img src={photoURL} alt='Avatar' className='avatar'></img>
<strong>Token:</strong> {currentUser.accessToken.substring(0, 20)} ...{' '}
{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
</p>
<p>
<strong>Id:</strong> {currentUser.id}
</p>
<p>
<strong>Email:</strong> {currentUser.email}
</p>
<strong>Authorities:</strong>
<ul>
{currentUser.roles &&
currentUser.roles.map((role, index) => <li key={index}>{role}</li>)}
</ul>
<button>
<Link to={'/profile/edit'}>Edit Profile</Link>
</button>
</div>
</div>
);
};
export default Profile;
在 UserServices.getProfile()
的 .then()
中使用以下内容:
setPhotoURL(response.data.profile_img_complete);
同时从您的 useEffect 中删除以下代码:
if (currentId && currentId.profile_img_complete) {
setPhotoURL(currentId.profile_img_complete);
}
我正在使用 spring 引导后端和 react.js 前端作为 Web 应用程序。用户登录后,它会将用户定向到他们的 Profile
,在那里他们将在屏幕上显示他们的用户名、个人资料图片和横幅。我开发了一个后端服务,returns 我在 Postman 上的 GET 请求正文中的必要信息,例如图像(个人资料或横幅)的 link。如果值为 null,我如何使用 React 在 profile_img_complete
中获取必要的 link 并将其插入到我已经有默认图像的图像中?我的演示用户在数据库中有一个图像可以使用,所以它不应该显示默认图像,但它是。任何帮助将不胜感激,这是邮递员信息的图片。
Profile.jsx:
import React, {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import {useSelector} from 'react-redux';
import UserProfileService from '../../services/user-profile.service';
import './styles/Profile.css';
const Profile = () => {
const {user: currentUser} = useSelector((state) => state.auth);
const {id: currentId} = useSelector((state) => state.auth);
const [content, setContent] = useState('');
const [photoURL, setPhotoURL] = useState('../../images/user-solid.svg');
//user-solid is the default image I want if the profile image link is null
useEffect(() => {
UserProfileService.getProfile().then(
(response) => {
setContent(response.data);
},
(error) => {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setContent(_content);
}
);
if (currentId && currentId.profile_img_complete) {
setPhotoURL(currentId.profile_img_complete);
}
}, [currentId]);
if (!currentUser) {
return <Link to='/login' />;
}
return (
<div className='page'>
<div className='profile-container'>
<header className='jumbotron'>
<h3>
<strong id='profile-name'>{currentUser.username}</strong> Profile
</h3>
</header>
<p>
<img src={photoURL} alt='Avatar' className='avatar'></img>
<strong>Token:</strong> {currentUser.accessToken.substring(0, 20)} ...{' '}
{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
</p>
<p>
<strong>Id:</strong> {currentUser.id}
</p>
<p>
<strong>Email:</strong> {currentUser.email}
</p>
<strong>Authorities:</strong>
<ul>
{currentUser.roles &&
currentUser.roles.map((role, index) => <li key={index}>{role}</li>)}
</ul>
<button>
<Link to={'/profile/edit'}>Edit Profile</Link>
</button>
</div>
</div>
);
};
export default Profile;
auth.js:
// We’re gonna import AuthService to make asynchronous HTTP requests with trigger one or more dispatch in the result.
// – register(): calls the AuthService.register(username, email, password) & dispatch setMessage if successful/failed
// – login(): calls the AuthService.login(username, password) & dispatch setMessage if successful/failed
// – logout(): calls the AuthService.logout().
// setMessage is imported from message slice that we’ve created above.
// We also need to use Redux Toolkit createAsyncThunk which provides a thunk that will take care of the action types and dispatching the right actions based on the returned promise.
//There are 3 async Thunks to be exported:
// register
// login
// logout
import {createSlice, createAsyncThunk} from '@reduxjs/toolkit';
import {setMessage} from './messages';
import AuthService from '../services/auth.service';
const user = JSON.parse(localStorage.getItem('user'));
export const register = createAsyncThunk(
'auth/register',
async ({username, email, password}, thunkAPI) => {
try {
const response = await AuthService.register(username, email, password);
thunkAPI.dispatch(setMessage(response.data.message));
return response.data;
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
thunkAPI.dispatch(setMessage(message));
return thunkAPI.rejectWithValue();
}
}
);
export const login = createAsyncThunk(
'auth/login',
async ({username, password}, thunkAPI) => {
try {
const data = await AuthService.login(username, password);
return {user: data};
} catch (error) {
const message =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
thunkAPI.dispatch(setMessage(message));
return thunkAPI.rejectWithValue();
}
}
);
export const logout = createAsyncThunk('auth/logout', async () => {
await AuthService.logout();
});
const initialState = user
? {isLoggedIn: true, user}
: {isLoggedIn: false, user: null};
const authSlice = createSlice({
name: 'auth',
initialState,
extraReducers: {
[register.fulfilled]: (state, action) => {
state.isLoggedIn = false;
},
[register.rejected]: (state, action) => {
state.isLoggedIn = false;
},
[login.fulfilled]: (state, action) => {
state.isLoggedIn = true;
state.user = action.payload.user;
},
[login.rejected]: (state, action) => {
state.isLoggedIn = false;
state.user = null;
},
[logout.fulfilled]: (state, action) => {
state.isLoggedIn = false;
state.user = null;
},
},
});
const {reducer} = authSlice;
export default reducer;
用户-profile.service.js:
import axios from 'axios';
import authHeader from './auth-header';
const API_URL = 'http://localhost:8080/';
const getProfile = () => {
return axios.get(API_URL + 'profile', {headers: authHeader()});
};
const user_profile = {
getProfile,
};
export default user_profile;
const image = req.query.profile_img
或 const {profile_img} = req.query
我假设图像中的数据是 UserProfileService.getProfile()
返回的 response.data
的值。当 UserProfileService.getProfile()
请求完成时,您需要更新 photoURL。此外,currentId 是一个字符串。它不包含 profile_img_complete
属性。
import React, {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import {useSelector} from 'react-redux';
import UserProfileService from '../../services/user-profile.service';
import './styles/Profile.css';
const Profile = () => {
const {user: currentUser} = useSelector((state) => state.auth);
const {id: currentId} = useSelector((state) => state.auth);
const [content, setContent] = useState('');
const [photoURL, setPhotoURL] = useState('../../images/user-solid.svg');
//user-solid is the default image I want if the profile image link is null
useEffect(() => {
UserProfileService.getProfile().then(
(response) => {
setContent(response.data);
if (response.data.profile_img_complete)
setPhotoURL(response.data.profile_img_complete);
},
(error) => {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setContent(_content);
}
);
}, [currentId]);
if (!currentUser) {
return <Link to='/login' />;
}
return (
<div className='page'>
<div className='profile-container'>
<header className='jumbotron'>
<h3>
<strong id='profile-name'>{currentUser.username}</strong> Profile
</h3>
</header>
<p>
<img src={photoURL} alt='Avatar' className='avatar'></img>
<strong>Token:</strong> {currentUser.accessToken.substring(0, 20)} ...{' '}
{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
</p>
<p>
<strong>Id:</strong> {currentUser.id}
</p>
<p>
<strong>Email:</strong> {currentUser.email}
</p>
<strong>Authorities:</strong>
<ul>
{currentUser.roles &&
currentUser.roles.map((role, index) => <li key={index}>{role}</li>)}
</ul>
<button>
<Link to={'/profile/edit'}>Edit Profile</Link>
</button>
</div>
</div>
);
};
export default Profile;
备用解决方案
state.auth
应该已经持有 profile_img_complete
。所以,你也可以这样做
import React, {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import {useSelector} from 'react-redux';
import UserProfileService from '../../services/user-profile.service';
import './styles/Profile.css';
const Profile = () => {
const {user: currentUser} = useSelector((state) => state.auth);
const auth = useSelector((state) => state.auth);
const {id: currentId} = useSelector((state) => state.auth);
const [content, setContent] = useState('');
const [photoURL, setPhotoURL] = useState(auth.profile_img_complete || '../../images/user-solid.svg');
//user-solid is the default image I want if the profile image link is null
useEffect(() => {
UserProfileService.getProfile().then(
(response) => {
setContent(response.data);
if (response.data.profile_img_complete)
setPhotoURL(response.data.profile_img_complete);
},
(error) => {
const _content =
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString();
setContent(_content);
}
);
}, [currentId]);
if (!currentUser) {
return <Link to='/login' />;
}
return (
<div className='page'>
<div className='profile-container'>
<header className='jumbotron'>
<h3>
<strong id='profile-name'>{currentUser.username}</strong> Profile
</h3>
</header>
<p>
<img src={photoURL} alt='Avatar' className='avatar'></img>
<strong>Token:</strong> {currentUser.accessToken.substring(0, 20)} ...{' '}
{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}
</p>
<p>
<strong>Id:</strong> {currentUser.id}
</p>
<p>
<strong>Email:</strong> {currentUser.email}
</p>
<strong>Authorities:</strong>
<ul>
{currentUser.roles &&
currentUser.roles.map((role, index) => <li key={index}>{role}</li>)}
</ul>
<button>
<Link to={'/profile/edit'}>Edit Profile</Link>
</button>
</div>
</div>
);
};
export default Profile;
在 UserServices.getProfile()
的 .then()
中使用以下内容:
setPhotoURL(response.data.profile_img_complete);
同时从您的 useEffect 中删除以下代码:
if (currentId && currentId.profile_img_complete) {
setPhotoURL(currentId.profile_img_complete);
}