yarn dev运行后端代码,再回到前端代码,yarn start运行就能获取到数据了,
因为在package.json中proxy设置了端口3001
Handling Login
App.js添加登录表单
const App = () => {
-- snip --
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
useEffect(() => {
noteService
.getAll().then(initialNotes => {
setNotes(initialNotes)
})
}, [])
// ...
const handleLogin = (event) => {
event.preventDefault()
console.log('logging in with', username, password)
}
return (
<div>
<h1>Notes</h1>
<Notification message={errorMessage} />
<form onSubmit={handleLogin}>
<div>
username
<input
type="text"
value={username}
name="Username"
onChange={({ target }) => setUsername(target.value)}
/>
</div>
<div>
password
<input
type="password"
value={password}
name="Password"
onChange={({ target }) => setPassword(target.value)}
/>
</div>
<button type="submit">login</button>
</form>
// ...
</div>
)
}
export default App
注意input元素中事件的写法
<input
type="text"
value={username}
name="Username"
onChange={({ target }) => setUsername(target.value)}
/>
target是input元素本身,加{}转化为对象
以上写法等价于
<input
type="text"
value={username}
name="Username"
onChange={( event ) => setUsername(event.target.value)}
/>
添加services/login.js模块
import axios from 'axios'
const baseUrl = '/api/login'
const login = async credentials => {
const response = await axios.post(baseUrl, credentials)
return response.data
}
export default { login }
实现登录功能
import loginService from './services/login'
const App = () => {
// ...
const [user, setUser] = useState(null)
// ...
const handleLogin = async (event) => {
event.preventDefault()
try {
const user = await loginService.login({
username, password
})
setUser(user)
setUsername('')
setPassword('')
} catch (exception) {
setErrorMessage('Wrong credentials')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
// ...
}
按条件渲染表单
当用户未登录时才显示登录表单
在App组件中添加2个辅助函数, 返回值是JSX
const App = () => {
// ...
const loginForm = () => (
<form onSubmit={handleLogin}>
// ...
</form>
)
const noteForm = () => (
<form onSubmit={addNote}>
// ...
</form>
)
return (
// ...
)
}
按条件渲染
const App = () => {
// ...
const loginForm = () => (
// ...
)
const noteForm = () => (
// ...
)
return (
<div>
// ...
{user === null && loginForm()}
{user !== null && noteForm()}
// ...
</div>
)
}
还可以使用三元运算符
{user === null ?
loginForm() :
<div>
<p>{user.name} logged-in</p>
{noteForm}
</div>
}
Creating new notes
修改services/notes.js, create时将token传入
import axios from 'axios'
const baseUrl = '/api/notes'
let token = null
const setToken = newToken => {
token = `bearer ${newToken}`
}
const getAll = () => {
const request = axios.get(baseUrl)
return request.then(response => response.data)
}
const create = async newObject => {
const config = {
headers: { Authorization: token },
}
const response = await axios.post(baseUrl, newObject, config)
return response.data
}
const update = (id, newObject) => {
const request = axios.put(`${ baseUrl } /${id}`, newObject)
return request.then(response => response.data)
}
export default { getAll, create, update, setToken }
登录时设置token的值
const handleLogin = async (event) => {
event.preventDefault()
try {
const user = await loginService.login({
username, password,
})
noteService.setToken(user.token)
setUser(user)
setUsername('')
setPassword('')
} catch (exception) {
// ...
}
}
Saving the token to browsers local storage
当页面重新渲染时user信息就没了,可以将用户信息存入localStorage
window.localStorage.setItem('name', 'juha tauriainen') // 存入
window.localStorage.getItem('name') // 读取
window.localStorage.removeItem('name') // 删除
window.localStorage.clear() // 清空
存储到本地存储的值称为DOMstrings,所以我们不能存储一个 Javascript 对象。
修改登录方法:
const handleLogin = async (event) => {
event.preventDefault()
try {
const user = await loginService.login({
username, password,
})
window.localStorage.setItem(
'loggedNoteappUser', JSON.stringify(user)
)
noteService.setToken(user.token)
setUser(user)
setUsername('')
setPassword('')
} catch (exception) {
// ...
}
}
在控制台查看localStorage
使用Effect hook, 加载页面时读取user信息
const App = () => {
// ...
useEffect(() => {
const loggedUserJSON = window.localStorage.getItem('loggedNoteappUser')
if (loggedUserJSON) {
const user = JSON.parse(loggedUserJSON)
setUser(user)
noteService.setToken(user.token)
}
}, [])
// ...
}
Exercise 5.1 - 5.4
克隆代码,安装依赖
git clone https://github.com/fullstack-hy/bloglist-frontend
npm install
npm start
get传递token
// ...
let token = null
const setToken = newToken => {
token = `bearer ${newToken}`
}
const getAll = async () => {
const config = {
headers: { Authorization: token }
}
const response = await axios.get(baseUrl, config)
return response.data
}
// ...
编写事件处理函数时,别忘了event.preventDefault()
如果要获取get或post之后的数据,别忘了要用async/await, 否则得到的是undefined
const createBlog = async (event) => {
event.preventDefault()
try {
const newBlog = await blogService.create(blog)
setBlogs(blogs.concat(newBlog))
} catch (error) {
console.log(error)
}
setBlog({
'title': '',
'author': '',
'url': ''
})
}