Loading

CS571 W7-React4/HW6

1. API 使用进阶

在过去的作业中,我们了解了 fetch 函数的 GET 方法。

与 API 交互所使用的函数均为 fetch (无论是采用 GET,POST 还是别的任何方法)。

一个通用的 fetch 函数案例:

fetch(`https://cs571.org/api/f23/hw6/messages?chatroom=${props.name}`,{
   method:"POST",
   credentials:"include",
   headers: {
       "X-CS571-ID": CS571.getBadgerId(),
       "Content-Type":"application/json"
   },
   body: JSON.stringify({
       "title":tit,
       "content":cnt
   })
   }).then(res=>res.json())
   .then(res=>{
   console.log(res);
   alert(res.msg);
   loadMessages();
})

对于非 GET 类型的请求,必须在代码开头标注 method:"POST" (或是PUT / DELETE)

四种基本请求操作:GET 读取,POST 创建PUT 更新,DELETE 删除

返回码

使用 res.status 方法来读取(请与 res.json() 作出区分,res.json() 是将返回值转为 JS object 的函数,而 res.status 是一个数值。

以下是常见的返回码:

HTTP Code Response Type
200s 成功
300s 重定向消息
400s 用户端出现问题
500s 服务器出现问题
HTTP Code Response
200 OK
304 已在本地有缓存
400 Bad Request(例如body中内容格式不符合要求)
401 未授权(例如没有Badger ID)
404 Not Found
409 冲突(例如试图 POST 已有的内容)
413 请求长度超标
500 内部服务器错误

注意事项

  1. 如果需要调取登陆状态进行需要权限的操作,则需要添加 credentials:"include" 一行
  2. 虽然传输的 body 本质是一个 JSON,但是它只接受字符串形式,所以使用 JSON.stringfy()
  3. 在含有 body 的请求当中,需要在 headers 里边注明 Content-Type 表示客户端传送内容的数据类型。例如: "Content-Type":"application/json"

2. 非受控组件

使用 useRef 方法。useref 是一个对不需要渲染的值的引用。

const remosk=useRef();
<Form.Control ref="remosk"></Form.Control>

remosk.current.value//获取当前输入框的值

头文件包含在 "react" 中,需要引入 "useRef" 属性。

非受控组件适合用于戳按钮后再一次提交,受控组件适合动态更新的场景(例如搜索框,随时根据当前的文本内容更新搜索建议)。

受控组件在效率上“似乎”要低于非受控组件,但实质上影响不大,因为受控组件只会修改虚拟 DOM 而不会修改真实 DOM,没有重新渲染的操作。因此 React 官方推荐使用受控组件

什么是Cookie?

HTTP 最大的特点是无连接无状态。Cookie 的作用是让浏览器在一段时间内认识你。

Cookie 是浏览一个网站时,由 Web 服务器存储在你的机器硬盘上的一个小的文本文件。当再次来到该网站时,浏览器会先检查有无对应的 Cookie 。如果有,浏览器会自动带上 Cookie 发送到服务端。

注:为什么我们需要显式地写上 credentials:"include"

CS571.org 和 localhost 是不同的域名。通常情况下,浏览器不允许 http 请求跨域携带 cookies 所以需要特殊标明

如果该 Cookie 被设置为 HTTP-Only 则它只能在服务端修改,客户端的 JS 脚本无法访问或修改它。

HW6:登录状态

在 HW6 中,我们需要实现这样一个功能:检测登录状态,如果在线则在导航栏内显示“登出”,如果离线,显示“登入”。

由于 HTTP-Only 不能被 JS 看到,所以需要使用 sessionStorage 配合 ContextProvider 来记录登陆状态。

4. 细节知识

1. 模板字符串

使用 `` 括起来。

内部可以使用$表示转义字符

示例代码:

fetch(`https://cs571.org/api/f23/hw6/messages?chatroom=${props.name}`,{})

2. HW6:页面强制刷新

在 submit 完修改后立刻调用一次 loadMessages

3. HW6:“不同聊天室” 的实现

导航栏:使用 Navbar 组件

下拉菜单:使用 NavDropdown 组件

HW6 在 BrowserRouter 部分的结构如下:

<BrowserRouter>
 <Routes>
    <Route path="/" element={<BadgerLayout chatrooms={chatrooms} />}>
      <Route index element={<BadgerChatHome />} />
      <Route path="/login" element={<BadgerLogin />}></Route>
      <Route path="/register" element={<BadgerRegister />}></Route>
      <Route path="/logout" element={<BadgerLogout />}></Route>
      {
        chatrooms.map(chatroom => {
          return <Route key={chatroom} path={`chatrooms/${chatroom}`} element={<BadgerChatroom name={chatroom} />} />
        })
      }
      <Route path="*" element={<BadgerNoMatch />} />
    </Route>
  </Routes>
</BrowserRouter>

可以看到,不同 Chatroom 的链接虽然不同,但使用的 React 组件是一致的,仅在传入的 props.name 上作区分。因此,在 Chatroom 间切换,页面不会重新加载。

故使用 useEffect(loadMessages, [props]); 而非 useEffect(loadMesages,[])

posted @ 2024-04-02 14:59  SS80194  阅读(38)  评论(0)    收藏  举报