FullStackOpen: React Custom Hooks

教程:FullStackOpen2022 / Part 7 / 自定义 hooks 本文以 routed-anecdotes 应用为例。对应练习 7.4-7.6。 1. React Hooks React 提供了多种不同的 Hooks,其中最常用的是 useState 和 useEffect,又比如 useImperativeHandle,它允许组件向其他组件提供其功能。 Hook 不是普通的函数,在使用这些 Hooks 时,必须遵守某些规则或限制: 不要在循环、条件或嵌套函数中调用 Hooks。即,总是在 React 函数的顶层使用 Hooks。 不要从普通的 JavaScript 函数中调用 Hooks。即,可以从 React 函数组件调用,或从自定义 Hooks 中调用 Hooks。 有现有的 ESlint 规则 eslint-plugin-react-hooks 可以用来验证应用是否正确使用 Hooks。 更多信息可见:useHooks 2. Custom Hooks React 提供了创建自定义的 Custom Hooks 的选项。 Custom Hooks 的主要目的是促进组件中使用的逻辑的重用,可以使用任何其他 Hooks。Custom Hooks 需要遵守 React Hooks 的规则,此外,名称必须以 use 这个词开头。 表单的每个字段都有自己的状态。为了使表单的状态与用户提供的数据保持同步,必须为每个输入元素注册一个适当的onChange处理程序。下面让试着自定义 useField Hook 来简化表单的状态管理。...

2022-06-17 · 1 min

FullStackOpen: React Router

每个不同的应用界面最好都有自己的 url 地址。在单页应用中,我们实际上总是在同一页上,即使有时处于不同的界面,路由地址仍然保持不变。 React 有 React Router 库,为管理 React 应用中的路由提供了一个解决方案。 教程:FullStackOpen2022 / Part 7 / React Router 本文以 routed-anecdotes 应用为例。对应练习 7.1-7.3。 注意: 本文中 React Router 版本为 5。版本 6 的 React Router 有一些突破性的改变,详见:React Router | Upgrading from v5。 1. 使用 React Router 安装 React Router: npm install react-router-dom 启用 React Router 提供的路由的应用: App.js: import React, { useState } from 'react' import { Switch, Route, Link, } from 'react-router-dom' //... const Menu = () => { return ( <div> <Link to="/">anecdotes</Link> <Link to="/create">create new</Link> <Link to="/about">about</Link> </div> ) } const App = () => { //....

2022-06-16 · 3 min

FullStackOpen: Redux

FullStackOpen: Redux 当应用变得庞大时,状态管理应当与 React 组件进行解耦。在这一章节,我们会引入 Redux 库,也是目前 React 应用生态中最流行的状态管理解决方案。 教程:FullStackOpen2022/Part 6 本文以 unicafe-redux 与 redux-anecdotes 应用为例。对应练习 6.1-6.18,6.21。 1. Flux 架构 Facebook 开发了 Flux 架构,提供了一种标准的方式来保存应用程序的状态以及如何修改它,使状态管理更加容易。 在 Flux 架构中,状态完全从 React-components 分离到自己的存储中。存储中的状态不会直接更改,而是使用不同的 actions进行更改。当一个操作改变了存储的状态时,视图会被重新渲染。 2. 在 React 中使用 Redux Redux 使用与 Flux 相同的原理,但是更简单一些。 安装 Redux: npm install redux 定义 reducer 处理 state 与 action 在 Redux 中,状态 state 存储在 store 中。存储的状态 state 通过 action 改变,action 对状态 state 的影响通过使用一个 reducer 来定义。 实际上,reducer 是一个函数,它以当前状态 state 和 action 为参数,返回一个新的状态 state。...

2022-05-16 · 6 min

FullStackOpen: React App E2E Test

教程:FullStackOpen2022/Part 5 本文中以 bloglist 应用为例。对应练习 5.11-5.21。 1. 使用 PropTypes 如果希望进一步定义组件 component 的属性值 props,可以通过 prop-types 包来实现。 npm install prop-types 使用 prop-types: components/Togglable.js: import PropTypes from 'prop-types' const Togglable = React.forwardRef((props, ref) => { // .. }) Togglable.propTypes = { buttonLabel: PropTypes.string.isRequired } Togglable.displayName = 'Togglable' export default Togglable components/LoginForm.js: import PropTypes from 'prop-types' const LoginForm = ({ login }) => { // ... } LoginForm.propTypes = { login: PropTypes.func.isRequired, } export default LoginForm 定义属性为 required 但该属性是 undefined 时,或传递给 prop 的类型是错误的时,应用仍然可以工作,但控制台会展示错误信息。...

2022-05-05 · 5 min

FullStackOpen: Bloglist React Front-End

教程:FullStackOpen2022/Part 5 本文中以 bloglist 应用为例。对应练习 5.1-5.10。 1. 实现登录登出功能 登录表单组件解耦 React 官方建议将共享状态提升到最近的共同父组件中去。因此,我们将登录表单的相关 state 移动到相应的组件中,组件只剩一个 props,即 login 函数,登录时,表单将调用该函数。 components/LoginForm.js: import React, { useState } from 'react' const LoginForm = ({ login }) => { const [username, setUsername] = useState('') const [password, setPassword] = useState('') const handleLogin = (e) => { e.preventDefault() login({ username, password, }) setUsername('') setPassword('') } return ( <> <h2>log in to application</h2> <form onSubmit={handleLogin}> <div> username <input type="text" value={username} name="Username" onChange={({ target }) => setUsername(target....

2022-05-02 · 4 min