持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
上一篇文章完成了用户数据的双向回显,即输入时后台及时获取到,并且在后台定义好初始数据也会在前台显示。
本篇略高能(自认为)
用户提交
当提交时,将email,username,password全部获取到并通过action指令传给网络进行请求。
此处用到react-thunk,thunk使我们可以在action中返回函数,而不是只能返回一个对象。然后我们可以在函数中做很多事情,比如发送异步的网络请求。
onSubmitForm = (email,username,password)=>(e)=>{
e.preventDefault()
this.props.onSubmitUser({email,username,password}) //增强
}
行为增强函数中定义该提交函数
onSubmitUser:(user)=>dispatch(action.registSubmit(user))
下面就可以去action中封装网络请求了。
网络请求:
在此之前,需要先准备好get,post,put,delete等请求方式,方便我们封装网络请求时使用。
初始baseurl为根路由,任何网络请求都是在baseUrl的基础上增加url才能得到指定路由地址的。
const baseURL = "http://localhost:8000/api/v1"
封装方式:
const method = {
GET:"GET",
POST:"POST",
PUT:"PUT",
DELETE:"DELETE",
}
具体请求方法,接收的参数需要根据之前在后台写的接口来写。
// GET
const getRequest = async (url)=>{
const response = await fetch(baseURL+url,{
method:method.GET,
headers:getHeaders()
})
return response.json()
}
// post
const postRequest = async (url,body)=>{
const response = await fetch(baseURL+url,{
method:method.POST,
headers:getHeaders(),
body:JSON.stringify(body) //js对象 => 字符串
})
return response.json()
}
// put
const putRequest = async (url,body)=>{
const response = await fetch(baseURL+url,{
method:method.PUT,
headers:getHeaders(),
body:JSON.stringify(body) //js对象 => 字符串
})
return response.json()
}
// DELETE :url携带id : 文章id / 评论id
const deleteRequest = async (url)=>{
const response = await fetch(baseURL+url,{
method:method.DELETE,
headers:getHeaders(),
})
return response.json()
}
之前在写后端接口的时候,是将token写在headers中的Authorization中的,所以也要封装一个获取token的方法,在此之前,要从后端拿到所有存在token的数据:
export const getData=(key)=>{
return JSON.parse(localStorage.getItem(key)) //获取token
}
const getHeaders = ()=>{
const token = getData('token')
console.log('token',token)
const headers ={
"Content-Type":contentType.JSON,
"Authorization":`Token ${token}`
}
return headers
}
集成redux
connected-react-router这个库帮我们实现了在 redux 中操作路由方法,并将路由变化的信息同步在 redux 的 store 中。
实现流程
- actions 封装 push、replace、go等主要方法
(在注册成功后跳转push至登录页面)
export const registSubmit =({email,username,password})=>{
//一旦是函数,thunk就拦截
return async(dispatch,getState)=>{
try {
//网络请求-----在这里!!!!!!网络请求!!!!
if(成功注册){
dispatch(push("/login")) //封装push方法
}
}
}
}
- middleware 拦截 actions 信息,触发封装好的 action 方法
thunk拦截action信息
创建history
export const history = createBrowserHistory()
集成redux
export const store = createStore(createRootReducer(history),
中间件拦截:applyMiddleware(routerMiddleware(history),thunk))
- reducer 新增 router 的state信息
reducer中
const createRootReducer = (history)=>combineReducers({
user:userReducer,
article:articleReducer,
router:connectRouter(history) //在这里监听路由变化
})
export default createRootReducer
- ConnectedRouter组件监听路由变化,更新路由信息到 store
<Provider store={store}>
<ConnectedRouter history={history}> //更新路由信息至store
<Switch>
<Route path="/" component={App} />
</Switch>
</ConnectedRouter>
</Provider>
依赖库
- history
- react-router
以上完成路由完整监听。
继续:
继续回来,从action处发送指令进行网络请求后,调用regist方法进行注册请求:
action.js中调用封装好的regist方法
const result = await request.user.regist(email,username,password)
request.js
regist:(email,username,password)=>
apiClient.post("/users",{user:{email,username,password}})
调用post方法:
apiClient.js中的post方法
// post url后缀为/user,body数据为email,username,password
const postRequest = async (url,body)=>{
const response = await fetch(baseURL+url,{
method:method.POST,
headers:getHeaders(),
body:JSON.stringify(body) //js对象 => 字符串
})
return response.json()
}
export default {
post:postRequest, //新增
}
当post提交时,检测email是否存在,如果存在则表示用户邮箱已经存在;如果不存在,则将密码进行md5加密并存入数据库中。(这里是在后台判断的)
截至,成功完成注册所有步骤。