React 全栈练习第 5 部分 async/await HTTP 请求的语法和承诺
React fullstack exercise part5 async/await syntax and promises for the HTTP request
我正在赫尔辛基大学学习 React with Fullstack。在其中一个练习中,我需要构建一个前端应用程序并将其与之前构建的后端服务器连接。
我需要实现一个 login/logout 函数。
问题出在我的 HandleLogin 部分。出于某种原因,如果我直接在前端 app.js 中对 axios HTTP 请求使用 promises。连接服务器没有问题。但是,如果我为登录功能创建一个新组件来处理登录按钮。我无法从服务器收到任何东西。我在 HandleLogin 中尝试了 console.log(user),它显示用户 axio/http 而不是 async/await.
谁能向我解释为什么会这样?非常感谢!
我的代码在这里。
App.js
import blogService from './services/blogs'
import loginService from './services/login'
import Blog from './components/Blog'
import LoginForm from './components/LoginForm'
import BlogForm from './components/BlogForm'
import Togglable from './components/Togglable'
import Notification from './components/Notification'
import axios from 'axios'
const App = () => {
const [blogs, setBlogs] = useState([])
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [user, setUser] = useState(null)
const [loginVisible, setLoginVisible] = useState(false)
const [Notification, setNotification] = useState("")
const [Toggle, setToggle] = useState(false)
useEffect(() => {
const Data = async () => {
const initialBlogs = await blogService.getAll()
setBlogs( initialBlogs )
}
Data()
}, [])
useEffect(() => {
const loggedUserJSON = window.localStorage.getItem('loggedBlogAppUser')
if (loggedUserJSON) {
const user = JSON.parse(loggedUserJSON)
setUser(user)
blogService.setToken(user.token)
}
}, [])
const addBlog = async (blogObject) => {
BlogFormRef.current.toggleVisibility()
if (blogObject.title !== '' && blogObject.author !== '' && blogObject.url !== '') {
const newBlog = await blogService.create(blogObject)
setBlogs(blogs.concat(newBlog))
setNotification(`A new blog ${blogObject.title} by ${blogObject.author} is added`)
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
} else {
setNotification('You must fill all fields to create a blog')
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
}
}
const BlogFormRef = useRef()
const blogUpdate = async (blogId, blogObject) => {
await blogService.update(blogId, blogObject)
const updatedBlog = {...blogObject, blogId}
setBlogs(blogs.map((blog) => (blog.id === updatedBlog.id ? updatedBlog : blog)))
}
const blogRemove = async (blogId) => {
await blogService.remove(blogId)
setBlogs(blogs.filter((blog) => blog.id !== blogId))
}
const handleLogin = async (event) => {
event.preventDefault()
try{
const user = await axios.post(`http://localhost:3001/api/login`, {username, password})
/*const user = await loginService.login({
username,
password
})*/ //this is not working
console.log(user)
console.log(user.data.name)
window.localStorage.setItem('loggedBlogAppUser', JSON.stringify(user))
blogService.setToken(user.data.token)
setUser(user)
setUsername('')
setPassword('')
setNotification(`User ${user.data.name} is logged in`)
} catch (exception) {
setNotification('Wrong username or password')
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
}
}
//console.log(user)
const handleLogout = () => {
window.localStorage.removeItem('loggedBlogAppUser')
document.location.reload()
}
const blogForm = () => (
<Togglable buttonLabel='new blog' cancelButtonLabel="Cancel" ref={BlogFormRef}>
<BlogForm createBlog={addBlog} />
</Togglable>
)
const loginForm = () => {
const hideWhenVisible = { display: loginVisible ? 'none' : ''}
const showWhenVisible = { display: loginVisible ? '' : 'none'}
return(
<div>
<div style={hideWhenVisible}>
<button onClick={() => setLoginVisible(true)}>log in</button>
</div>
<div style={showWhenVisible}>
<LoginForm
username={username}
password={password}
handleUsernameChange={({target}) => setUsername(target.value)}
handlePasswordChange={({target}) => setPassword(target.value)}
handleSubmit={handleLogin}/>
</div>
</div>
)
}
return (
<div>
<h2>Blog11</h2>
{user && (
<div>
{user.data.name} is logged in
<button onClick={handleLogout}>Logout</button>
</div>
)}
<div>
{user === null ? loginForm()
:(
<>
{blogForm()}
<div>
{blogs.map(blog =>
<Blog
key={blog.id}
blog={blog}
blogUpdate={blogUpdate}
blogRemove={blogRemove}/>
)}
</div>
</>
)
}
</div>
</div>
)
}
export default App
登录服务
const baseUrl = `/api/login`
const login = async (credentials) => {
const response = await axios.post(baseUrl, credentials)
return response.data
}
export default login
第一次在Whosebug上提问。谢谢大家的耐心等待。
我放弃了使用独立模块。相反,我在 App.js 中使用了 await axios.post 并且没有问题。
try{
const user = await axios.post(`http://localhost:3001/api/login`, {username, password})
/*const user = await loginService.login({
username,
password
})*/ //this is not working
//console.log(user)
//console.log(user.data.name)
window.localStorage.setItem('loggedBlogAppUser', JSON.stringify(user))
blogService.setToken(user.data.token)
setUser(user)
setUsername('')
setPassword('')
setNotification(`User ${user.data.name} is logged in`)
} catch (exception) {
setNotification('Wrong username or password')
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
}
}
我正在赫尔辛基大学学习 React with Fullstack。在其中一个练习中,我需要构建一个前端应用程序并将其与之前构建的后端服务器连接。
我需要实现一个 login/logout 函数。
问题出在我的 HandleLogin 部分。出于某种原因,如果我直接在前端 app.js 中对 axios HTTP 请求使用 promises。连接服务器没有问题。但是,如果我为登录功能创建一个新组件来处理登录按钮。我无法从服务器收到任何东西。我在 HandleLogin 中尝试了 console.log(user),它显示用户 axio/http 而不是 async/await.
谁能向我解释为什么会这样?非常感谢!
我的代码在这里。
App.js
import blogService from './services/blogs'
import loginService from './services/login'
import Blog from './components/Blog'
import LoginForm from './components/LoginForm'
import BlogForm from './components/BlogForm'
import Togglable from './components/Togglable'
import Notification from './components/Notification'
import axios from 'axios'
const App = () => {
const [blogs, setBlogs] = useState([])
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [user, setUser] = useState(null)
const [loginVisible, setLoginVisible] = useState(false)
const [Notification, setNotification] = useState("")
const [Toggle, setToggle] = useState(false)
useEffect(() => {
const Data = async () => {
const initialBlogs = await blogService.getAll()
setBlogs( initialBlogs )
}
Data()
}, [])
useEffect(() => {
const loggedUserJSON = window.localStorage.getItem('loggedBlogAppUser')
if (loggedUserJSON) {
const user = JSON.parse(loggedUserJSON)
setUser(user)
blogService.setToken(user.token)
}
}, [])
const addBlog = async (blogObject) => {
BlogFormRef.current.toggleVisibility()
if (blogObject.title !== '' && blogObject.author !== '' && blogObject.url !== '') {
const newBlog = await blogService.create(blogObject)
setBlogs(blogs.concat(newBlog))
setNotification(`A new blog ${blogObject.title} by ${blogObject.author} is added`)
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
} else {
setNotification('You must fill all fields to create a blog')
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
}
}
const BlogFormRef = useRef()
const blogUpdate = async (blogId, blogObject) => {
await blogService.update(blogId, blogObject)
const updatedBlog = {...blogObject, blogId}
setBlogs(blogs.map((blog) => (blog.id === updatedBlog.id ? updatedBlog : blog)))
}
const blogRemove = async (blogId) => {
await blogService.remove(blogId)
setBlogs(blogs.filter((blog) => blog.id !== blogId))
}
const handleLogin = async (event) => {
event.preventDefault()
try{
const user = await axios.post(`http://localhost:3001/api/login`, {username, password})
/*const user = await loginService.login({
username,
password
})*/ //this is not working
console.log(user)
console.log(user.data.name)
window.localStorage.setItem('loggedBlogAppUser', JSON.stringify(user))
blogService.setToken(user.data.token)
setUser(user)
setUsername('')
setPassword('')
setNotification(`User ${user.data.name} is logged in`)
} catch (exception) {
setNotification('Wrong username or password')
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
}
}
//console.log(user)
const handleLogout = () => {
window.localStorage.removeItem('loggedBlogAppUser')
document.location.reload()
}
const blogForm = () => (
<Togglable buttonLabel='new blog' cancelButtonLabel="Cancel" ref={BlogFormRef}>
<BlogForm createBlog={addBlog} />
</Togglable>
)
const loginForm = () => {
const hideWhenVisible = { display: loginVisible ? 'none' : ''}
const showWhenVisible = { display: loginVisible ? '' : 'none'}
return(
<div>
<div style={hideWhenVisible}>
<button onClick={() => setLoginVisible(true)}>log in</button>
</div>
<div style={showWhenVisible}>
<LoginForm
username={username}
password={password}
handleUsernameChange={({target}) => setUsername(target.value)}
handlePasswordChange={({target}) => setPassword(target.value)}
handleSubmit={handleLogin}/>
</div>
</div>
)
}
return (
<div>
<h2>Blog11</h2>
{user && (
<div>
{user.data.name} is logged in
<button onClick={handleLogout}>Logout</button>
</div>
)}
<div>
{user === null ? loginForm()
:(
<>
{blogForm()}
<div>
{blogs.map(blog =>
<Blog
key={blog.id}
blog={blog}
blogUpdate={blogUpdate}
blogRemove={blogRemove}/>
)}
</div>
</>
)
}
</div>
</div>
)
}
export default App
登录服务
const baseUrl = `/api/login`
const login = async (credentials) => {
const response = await axios.post(baseUrl, credentials)
return response.data
}
export default login
第一次在Whosebug上提问。谢谢大家的耐心等待。
我放弃了使用独立模块。相反,我在 App.js 中使用了 await axios.post 并且没有问题。
try{
const user = await axios.post(`http://localhost:3001/api/login`, {username, password})
/*const user = await loginService.login({
username,
password
})*/ //this is not working
//console.log(user)
//console.log(user.data.name)
window.localStorage.setItem('loggedBlogAppUser', JSON.stringify(user))
blogService.setToken(user.data.token)
setUser(user)
setUsername('')
setPassword('')
setNotification(`User ${user.data.name} is logged in`)
} catch (exception) {
setNotification('Wrong username or password')
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
}
}