当前位置: 首页 > news >正文

网站你懂我意思正能量晚上在线观看不用下载免费asp黑网站源码

网站你懂我意思正能量晚上在线观看不用下载免费,asp黑网站源码,抖音搜索seo排名优化,网站建设评估3 状态管理 随着应用不断变大#xff0c;应该更有意识的去关注应用状态如何组织#xff0c;以及数据如何在组件之间流动。冗余或重复的状态往往是缺陷的根源。 3.1 用State响应输入 3.1.1 声明式地考虑UI 总体步骤如下#xff1a; 定位组件中不同的视图状态 确定是什么…3 状态管理 随着应用不断变大应该更有意识的去关注应用状态如何组织以及数据如何在组件之间流动。冗余或重复的状态往往是缺陷的根源。 3.1 用State响应输入 3.1.1 声明式地考虑UI 总体步骤如下 定位组件中不同的视图状态 确定是什么触发了这些 state 的改变 人为输入人为输入一般需要事件处理函数计算机输入 表示内存中的 state需要使用 useState 需要让“变化的部分”尽可能的少可以先从必须的状态开始刚开始若不确定可以设置多一些视图状态之后不断尝试重构state 删除任何不必要的 state 变量 这个 state 是否会导致矛盾 相同的信息是否已经在另一个 state 变量中存在 你是否可以通过另一个 state 变量的相反值得到相同的信息 Reducer 可以合并多个状态变量到一个对象中并巩固所有相关的逻辑 连接事件处理函数去设置 state 创建事件处理函数去设置 state 变量。 同时展示大量的视图状态这样的页面通常被称作living styleguide或者storybook 挑战这个表单在两种模式间切换编辑模式你可以看到输入框查看模式你只能看到结果。按钮的标签会根据你所处的模式在“编辑”和“保存”两者中切换。当你改变输入框的内容时欢迎信息会最下面实时更新。 import {useState} from react;export default function EditProfile() {const [display, setDisplay] useState(false);const [person, setPerson] useState({firstName: Joe,lastName: Stan});function handleFirstNameChange(e) {setPerson({...person,[e.target.name]: e.target.value})}function handleLastNameChange(e) {setPerson({...person,[e.target.name]: e.target.value})}return (form onSubmit{e {e.preventDefault(),setDisplay(!display)}}labelFirst name:{ }{display ? input namefirstNamevalue{person.firstName}onChange{handleFirstNameChange} / :b{person.firstName}/b}/labellabelLast name:{ }{display ? input namelastName value{person.lastName}onChange{handleLastNameChange} / :b{person.lastName}/b}/labelbutton typesubmit{display ? Save : Edit} Profile/buttonpiHello, {person.firstName} {person.lastName}!/i/p/form); } updateDOM函数展示了当你设置 state 时React 在幕后都做了什么. // index.js let firstName Jane; let lastName Jacobs; let isEditing false;function handleFormSubmit(e) {e.preventDefault();setIsEditing(!isEditing); }function handleFirstNameChange(e) {setFirstName(e.target.value); }function handleLastNameChange(e) {setLastName(e.target.value); }function setFirstName(value) {firstName value;updateDOM(); }function setLastName(value) {lastName value;updateDOM(); }function setIsEditing(value) {isEditing value;updateDOM(); }function updateDOM() {if (isEditing) {editButton.textContent Save Profile;hide(firstNameText);hide(lastNameText);show(firstNameInput);show(lastNameInput);} else {editButton.textContent Edit Profile;hide(firstNameInput);hide(lastNameInput);show(firstNameText);show(lastNameText);}firstNameText.textContent firstName;lastNameText.textContent lastName;helloText.textContent (Hello firstName lastName !); }function hide(el) {el.style.display none; }function show(el) {el.style.display ; }let form document.getElementById(form); let editButton document.getElementById(editButton); let firstNameInput document.getElementById(firstNameInput); let firstNameText document.getElementById(firstNameText); let lastNameInput document.getElementById(lastNameInput); let lastNameText document.getElementById(lastNameText); let helloText document.getElementById(helloText); form.onsubmit handleFormSubmit; firstNameInput.oninput handleFirstNameChange; lastNameInput.oninput handleLastNameChange; /* index.html */ form idformlabelFirst name:b idfirstNameTextJane/binputidfirstNameInputvalueJanestyledisplay: none/labellabelLast name:b idlastNameTextJacobs/binputidlastNameInputvalueJacobsstyledisplay: none/labelbutton typesubmit ideditButtonEdit Profile/buttonpi idhelloTextHello, Jane Jacobs!/i/p /formstyle * { box-sizing: border-box; } body { font-family: sans-serif; margin: 20px; padding: 0; } label { display: block; margin-bottom: 20px; } /style 3.2 选择state结构 3.1.1 构建state的原则 合并关联的 state 如果某两个 state 变量总是一起变化则将它们统一成一个 state 变量可能更好另一种情况是将数据整合到一个对象或一个数组中时不知道需要多少个 state 片段 避免互相矛盾的 state 避免冗余的 state “镜像”一些 prop 属性会导致混淆建议使用常量 function Message({ messageColor }) {const color messageColor;只有当想要 忽略特定 props 属性的所有更新时将 props “镜像”到 state 才有意义。按照惯例prop 名称以 initial 或 default 开头以阐明该 prop 的新值将被忽略 function Message({ initialColor }) {// 这个 color state 变量用于保存 initialColor 的 **初始值**。// 对于 initialColor 属性的进一步更改将被忽略。const [color, setColor] useState(initialColor);避免重复的 state 避免深度嵌套的 state 3.3 在组件间共享状态状态提升 当编写一个组件时你应该考虑哪些信息应该由父组件控制通过传递 props哪些信息应该由内部state控制通过 state。 进行状态提升的步骤 从子组件中 移除 state 。从父组件 传递 props。为子组件的共同父组件添加 state 并将其与事件处理函数一起向下传递 3.4 对state进行保留和重置 React 使用树形结构来对开发者创造的 UI 进行管理和建模。 3.4.1 state与树中的某个位置相关联 根据组件在 UI 树中的位置React 将它所持有的每个 state 与正确的组件关联起来。 React 在移除一个组件时也会销毁它的 state。下面是一个组件的添加与删除。 只要一个组件还被渲染在 UI 树的相同位置React 就会保留它的 state。 如果它被移除或者一个不同的组件被渲染在相同的位置那么 React 就会丢掉它的 state。 3.4.2 相同位置的相同组件会保留state 更新 App 的状态不会重置 Counter因为 Counter 始终保持在同一位置。 import { useState } from react;export default function App() {const [isFancy, setIsFancy] useState(false);return (div{isFancy ? (Counter isFancy{true} / ) : (Counter isFancy{false} / )}labelinputtypecheckboxchecked{isFancy}onChange{e {setIsFancy(e.target.checked)}}/使用好看的样式/label/div); }function Counter({ isFancy }) {const [score, setScore] useState(0);const [hover, setHover] useState(false);let className counter;if (hover) {className hover;}if (isFancy) {className fancy;}return (divclassName{className}onPointerEnter{() setHover(true)}onPointerLeave{() setHover(false)}h1{score}/h1button onClick{() setScore(score 1)}加一/button/div); } 对 React 来说重要的是组件在 UI 树中的位置,而不是在 JSX 中的位置 3.4.3 相同位置的不同组件会重置state import { useState } from react;export default function App() {const [isPaused, setIsPaused] useState(false);return (div{isPaused ? (p待会见/p ) : (Counter / )}labelinputtypecheckboxchecked{isPaused}onChange{e {setIsPaused(e.target.checked)}}/休息一下/label/div); }function Counter() {const [score, setScore] useState(0);const [hover, setHover] useState(false);let className counter;if (hover) {className hover;}return (divclassName{className}onPointerEnter{() setHover(true)}onPointerLeave{() setHover(false)}h1{score}/h1button onClick{() setScore(score 1)}加一/button/div); } 当 Counter 变为 p 时Counter 会被移除同时 p 被添加。 当切换回来时p 会被删除而 Counter 会被添加。 刚开始 div 的第一个子组件是一个 Counter。但是当切换成 p 时React 将 Counter 从 UI 树中移除了并销毁了它的状态。 当在相同位置渲染不同的组件时组件的整个子树都会被重置 当 section 变为 div 时section 会被删除新的 div 被添加 当切换回来时div 会被删除新的 section 被添加。 如果想在重新渲染时保留 state几次渲染中的树形结构就应该相互“匹配”。 3.4.4 在相同位置重置相同组件的state 方法1将组件渲染在不同位置(适用于只有少数几个组件) 方法2使用key赋予每个组件一个明确的身份 {isPlayerA ? (Counter keyTaylor personTaylor / ) : (Counter keySarah personSarah / )}请记住 key 不是全局唯一的。它们只能指定 父组件内部 的顺序。 3.4.5 使用key重置表单 给Chat组件添加一个 key,就可以保证每次选择一个不同的收件人时Chat组件包括其下方树中的state就会被重新创建。 Chat key{to.id} contact{to} /3.4.6 为被移除的组件保留state 比如聊天应用 如果UI比较简单就可以使用CSS把其他聊天隐藏起来进行状态提升让父组件保存信息使用其他数据源 3.5 迁移状态逻辑至Reducer中 3.5.1 使用reducer整合状态逻辑 Reducer 是处理状态的另一种方式。你可以通过三个步骤将 useState 迁移到 useReducer 将设置状态的逻辑 修改 成 dispatch 的一个 action 比如下面这段代码 function handleAddTask(text) {setTasks([...tasks,{id: nextId,text: text,done: false,},]); }function handleChangeTask(task) {setTasks(tasks.map((t) {if (t.id task.id) {return task;} else {return t;}})); }function handleDeleteTask(taskId) {setTasks(tasks.filter((t) t.id ! taskId)); }移除所有状态设置逻辑只留下三个事件处理函数。通过事件处理函数 dispatch 一个 action来指明 “用户刚刚做了什么”。状态更新逻辑则保存在其他地方)修改后的代码如下: function handleAddTask(text) {dispatch(// action 对象{type: added,id: nextId,text: text,}); }function handleChangeTask(task) {dispatch({type: changed,task: task,}); }function handleDeleteTask(taskId) {dispatch({type: deleted,id: taskId,}); }action 对象可以有多种结构。 按照惯例通常会添加一个字符串类型的 type 字段来描述发生了什么并通过其它字段传递额外的信息。type 是特定于组件的在这个例子中 added 和 addded_task 都可以。选一个能描述清楚发生的事件的名字 dispatch({// 针对特定的组件type: what_happened,// 其它字段放这里 });编写 一个 reducer 函数 reducer 函数就是你放置状态逻辑的地方。它接受两个参数分别为当前 state 和 action 对象并且返回的是更新后的 state: function yourReducer(state, action) {// 给 React 返回更新后的状态 }在这个例子中要将状态设置逻辑从事件处理程序移到 reducer 函数中你需要 声明当前状态tasks作为第一个参数声明 action 对象作为第二个参数从 reducer 返回 下一个 状态React 会将旧的状态设置为这个最新的状态。 function tasksReducer(tasks, action) {if (action.type added) {return [...tasks,{id: action.id,text: action.text,done: false,},];} else if (action.type changed) {return tasks.map((t) {if (t.id action.task.id) {return action.task;} else {return t;}});} else if (action.type deleted) {return tasks.filter((t) t.id ! action.id);} else {throw Error(未知 action: action.type);} }上面语句用了if/else语句但在reducers中使用switch语句更加一目了然 function tasksReducer(tasks, action) {switch (action.type) {case added: {return [...tasks,{id: action.id,text: action.text,done: false,},];}case changed: {return tasks.map((t) {if (t.id action.task.id) {return action.task;} else {return t;}});}case deleted: {return tasks.filter((t) t.id ! action.id);}default: {throw Error(未知 action: action.type);}} }在组件中 使用 reducer。 事件处理程序只通过派发 action 来指定 发生了什么而 reducer 函数通过响应 actions 来决定 状态如何更新。 3.5.2 对比useState和useReducer 代码体积UI组件少可以用useState,组件复杂用useReducer可读性依据状态更新逻辑复杂程度而定简单时useState复杂时useReducer可调试性useReducer更佳可以通过打印日志来调试可测试性reducer函数是一个纯函数可以单独进行测试 3.5.3 编写一个好的reducer函数 reducer必须是一个纯函数每个action都描述了一个单一的用户交互即便它会引发多个数据的变化 3.5.4 使用Immer简化reducers 引入useImmerReducer: import { useImmerReducer } from use-immer;使用draft.函数修改state: function tasksReducer(draft, action) {switch (action.type) {case added: {draft.push({id: action.id,text: action.text,done: false,});break;}case changed: {const index draft.findIndex((t) t.id action.task.id);draft[index] action.task;break;}case deleted: {return draft.filter((t) t.id ! action.id);}default: {throw Error(未知 action action.type);}} }3.6 使用Context深层传递参数 Context 允许父组件向其下层无论多深的任何组件提供信息而无需通过 props 显式传递。 创建context // LevelContext.js import { createContext } from react;export const LevelContext createContext(1); 使用context import { useContext } from react; import { LevelContext } from ./LevelContext.js;export default function Heading({ children }) {const level useContext(LevelContext);// ... }提供context 用 context provider 包裹起来 以提供 LevelContext 给它们 import { LevelContext } from ./LevelContext.js;export default function Section({ level, children }) {return (section classNamesectionLevelContext.Provider value{level}{children}/LevelContext.Provider/section); }Context 让你可以编写“适应周围环境”的组件并且根据在哪 或者说 在哪个 context 中来渲染它们不同的样子。不同的 React context 不会覆盖彼此。Context 会穿过中间的任何组件。 3.6.1 context的使用场景 主题 如果你的应用允许用户更改其外观例如暗夜模式你可以在应用顶层放一个 context provider并在需要调整其外观的组件中使用该 context。当前账户 许多组件可能需要知道当前登录的用户信息。将它放到 context 中可以方便地在树中的任何位置读取它。路由 大多数路由解决方案在其内部使用 context 来保存当前路由。**状态管理**通常 将 reducer 与 context 搭配使用来管理复杂的状态并将其传递给深层的组件来避免过多的麻烦。 3.7 使用Reducer和Context拓展应用 步骤 创建 context。将 state 和 dispatch 放入 context。在组件树的任何地方 使用 context。 为子组件提供 state 和 dispatch 函数 创建两个 context (一个用于 state,一个用于 dispatch 函数)。 import { createContext } from react;export const TasksContext createContext(null); export const TasksDispatchContext createContext(null);让组件的 context 使用 reducer。 export function TasksProvider({ children }) {const [tasks, dispatch] useReducer(tasksReducer, initialTasks);return (TasksContext.Provider value{tasks}TasksDispatchContext.Provider value{dispatch}{children}/TasksDispatchContext.Provider/TasksContext.Provider); } // 也可以从 TasksContext.js 中导出使用 context 的函数 export function useTasks() {return useContext(TasksContext); }export function useTasksDispatch() {return useContext(TasksDispatchContext); }使用组件中需要读取的 context。 // 组件可以通过以下函数读取 context const tasks useTasks(); const dispatch useTasksDispatch();像 useTasks 和 useTasksDispatch 这样的函数被称为自定义 Hook 如果你的函数名以 use 开头它就被认为是一个自定义 Hook。
http://www.tj-hxxt.cn/news/222199.html

相关文章:

  • 做pc端网站讯息六安网事
  • 班级网站建设主题百度知道合伙人答题兼职
  • 西昌有没有可以做网站的公司深圳画册设计公司哪家好
  • 甘肃省建设厅注册中心网站首页外贸网站建设公司服务
  • 英文网站建设求职简历
  • 无锡新区规划建设环保局网站做app和网站哪个比较好用
  • 合肥网站建设团队平面设计和网页设计哪个工资高
  • 天津网站建设渠道wordpress 国外服务器
  • 游戏网站风控怎么做深圳优定软件网站建设
  • 深圳网站开发找哪里谁能做网站开发
  • 网广州建网站站制作广州网站建设建航科技公司
  • 房产网站做那个比较好坂田杨美企业网站建设
  • 温州做网站找哪家好网站屏蔽中国ip
  • 织梦网站搬家教程辽宁省建设工程信息网网址
  • 百度小程序如何做网站商城建设开发
  • 网站建设规划申请旅游景点网页
  • 男鞋 东莞网站建设软件技术 网站建设教程
  • 无锡企业网站设计公司百度官网认证多少钱一年
  • 汕头网站推广seo物流 网站 模板
  • 到位app做网站需要些程序广州网站开发 细致广州亦客网络
  • seo优化网站优化排名怎么做app推广和宣传
  • 简单的房源展示网站开发最新网游网络游戏新开服
  • 怎么做家具定制网站石家庄app制作
  • 微网站系统软件首页设计
  • 学校网站建设市场分析做网店装修的网站有哪些内容
  • 做seo排名好的网站本地环境建设网站
  • h5网站免费建设wordpress 论坛社区
  • 充值中心网站怎么做做网站客户尾款老不给怎么办
  • 网站建设培训报名wordpress posts
  • 网站开发个人简历word下载视频剪辑培训班学费一般多少