15-blog-前端注册逻辑

209 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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加密并存入数据库中。(这里是在后台判断的)

image.png

截至,成功完成注册所有步骤。