重庆市住房和城乡建设厅官方网站查询动静分离网站架构

张小明 2026/1/15 23:36:47
重庆市住房和城乡建设厅官方网站查询,动静分离网站架构,创建微信公众号教程,做网站信息在前端开发的学习路径中#xff0c;Todo List#xff08;待办事项清单#xff09;被称为“Hello World”级别的实战项目。虽然看起来简单#xff0c;但它涵盖了 CRUD#xff08;增删改查#xff09;、组件拆分、状态管理等核心逻辑。 今天我们将通过一份基于 Vite React…在前端开发的学习路径中Todo List待办事项清单被称为“Hello World”级别的实战项目。虽然看起来简单但它涵盖了 CRUD增删改查、组件拆分、状态管理等核心逻辑。今天我们将通过一份基于 Vite React Stylus 的源码深入拆解 React 的核心开发模式。1. 项目架构与组件化思维React 的核心思想是组件化。我们将 UI 拆分成独立的、可复用的部分。在这个项目中我们的组件结构非常清晰App(父组件): 整个应用的容器负责“持有数据”和“管理逻辑”。它是唯一的数据源Source of Truth。TodoInput(子组件): 负责用户输入将新任务传递给父组件。TodoList(子组件): 负责展示任务列表处理完成/删除操作。TodoStarts(子组件): 负责展示统计信息总数、剩余、已完成并提供清除功能。这种结构体现了 React 开发的一个重要原则状态提升Lifting State Up。因为TodoList需要展示数据TodoStarts需要统计数据所以我们将数据统一放在它们的共同父组件App中管理。2. 核心知识点拆解2.1 State 管理与 Hooks 高级用法在App.jsx中我们使用了useState来管理任务列表数据。// App.jsx const [todos, setTodos] useState(() { // 知识点Lazy Initialization (惰性初始化) const saved localStorage.getItem(todos); return saved ? JSON.parse(saved) : []; });解析通常我们写 useState([])但这里传入了一个函数。为什么localStorage.getItem是同步操作如果直接写在组件体内每次组件重新渲染都会执行影响性能。惰性初始化传入函数后React 只会在组件首次渲染时执行该逻辑后续渲染会跳过这是性能优化的一个小技巧。2.2 受控组件 (Controlled Components)在TodoInput.jsx中我们处理用户输入的方式与 Vue 的v-model不同。// TodoInput.jsx const [inputValue, setInputValue] useState(); // ... render input typetext value{inputValue} // 1. 绑定状态 onChange{e setInputValue(e.target.value)} // 2. 监听变化并更新状态 /解析React 提倡单向数据流。输入框的值由 React state (inputValue) 控制。用户的输入触发onChange。setInputValue 更新 stateReact 重新渲染组件输入框显示新值。这被称为受控组件它保证了数据和视图的严格同步。2.3 组件通信父传子 (Props)数据如何从App流向TodoList通过Props。// App.jsx (父组件) TodoList todos{todos} ... / // TodoList.jsx (子组件) const TodoList (props) { const { todos } props; // 解构获取数据 // ... }解析父组件将 todos 数组作为属性传递给子组件子组件只能读取严禁直接修改 Props。这是 React 数据流向单一性的铁律。2.4 组件通信子传父 (回调函数)子组件想要修改数据怎么办例如用户在 TodoInput 点击了添加或者在 TodoList 点击了删除。答案父组件传递“修改数据的方法”给子组件。场景一添加任务// App.jsx (父组件定义方法) const addTodo (text) { setTodos([...todos, { id: Date.now(), text, completed: false }]) } // 传递给子组件 TodoInput onAdd{addTodo} / // TodoInput.jsx (子组件调用) const handleSubmit (e) { e.preventDefault(); onAdd(inputValue); // 调用父组件传下来的函数 setInputValue(); }场景二兄弟组件通信间接TodoInput 添加的数据最终显示在了 TodoList 中。它们之间没有直接联系而是通过TodoInput通知App更新 state。Appstate 变化触发重新渲染。App将新的todos传给TodoList。这就是状态共享的魅力。2.5 交互逻辑详解不可变数据的删除与更新在 React 中更新状态State有一个核心原则永远不要直接修改 State而是用新数据替换旧数据。这一点在删除和勾选操作中体现得淋漓尽致。1. 删除功能Filter 的妙用点击删除按钮时我们需要移除列表中的某一项。在App.jsx中我们没有使用数组的splice方法因为它会直接修改原数组而是使用了filter。// App.jsx const deleteTodo (id) { // 知识点Immutable Update (不可变更新) // filter 返回一个新数组不包含被删除的那一项 setTodos(todos.filter(todo todo.id ! id)) }在 UI 组件TodoList.jsx中我们需要注意事件绑定的写法// TodoList.jsx button onClick{() onDelete(todo.id)}Delete/button⚠️ 新手易错点一定要写成箭头函数 () onDelete(todo.id)。如果写成 onClick{onDelete(todo.id)}函数会在组件渲染时立即执行导致无限循环报错。2. 勾选切换Map 与展开运算符这是 React 数组更新中最常见的模式。当用户点击 Checkbox 时我们需要把数组中特定 ID的那一项的completed状态取反同时保持其他项不变。// App.jsx const toggleTodo (id) { setTodos(todos.map(todo // 遍历每一个 item找到 id 匹配的那一个 todo.id id ? { ...todo, // 知识点Spread Operator (展开运算符) 复制原有属性 completed: !todo.completed // 覆盖 completed 属性 } : todo // id 不匹配的项保持原样 )) }逻辑解析todos.map生成一个全新的数组保证不修改原todos引用。...todo利用 ES6 的展开运算符将旧对象的所有属性id, text复制到新对象中。completed: !todo.completed单独覆盖我们需要修改的属性。在TodoList.jsx中我们将这个逻辑绑定到 input 的onChange事件上同时利用checked属性实现受控组件的双向绑定效果// TodoList.jsx input typecheckbox checked{todo.completed} // 视图状态依赖数据 onChange{() onToggle(todo.id)} // 数据更新依赖交互 /同时也利用这个状态来动态控制 CSS 类名实现完成时的划线样式li key{todo.id} className{todo.completed ? completed : }2.6 列表渲染与 Key在TodoList.jsx中我们使用map方法渲染列表// TodoList.jsx todos.map(todo ( li key{todo.id} className{todo.completed ? completed : } {/* ...内容 */} /li ))解析Key 的重要性React 需要key来识别哪些元素改变了、添加了或删除了。这里我们使用了todo.id(时间戳) 作为唯一标识。切记不要使用数组索引(index)作为 key这在列表顺序变化时会导致严重的渲染错误或性能问题。条件渲染我们使用三元运算符todos.length 0 ? (...) : (...)来处理空状态的展示。2.7 副作用处理 (useEffect)如何实现数据持久化刷新页面数据不丢失我们使用了useEffect。// App.jsx useEffect(() { localStorage.setItem(todos, JSON.stringify(todos)); }, [todos])解析useEffect用于处理副作用Side Effects比如数据获取、订阅、手动修改 DOM 等。依赖数组[todos]这意味着每当todos状态发生变化时React 就会执行这个函数将最新的数据同步到 LocalStorage。2.8 逻辑复用与短路运算在TodoStarts.jsx中有一个很优雅的条件渲染写法// TodoStarts.jsx { completed 0 ( button onClick{onClearCompleted}Clear Completed/button ) }解析利用 JavaScript 的逻辑与 () 运算。只有当 completed 0 为真时后面的 Button 才会渲染。这比写 if/else 要简洁得多。3. 总结通过这个小小的 Todo List我们完整实践了 React 开发的“黄金法则”数据驱动视图UI 是 State 的投影 (UI f(State))。单向数据流数据向下流动 (Props)事件向上冒泡 (Callback)。不可变性在App.jsx的deleteTodo等方法中我们使用了filter和map返回新数组而不是直接修改原数组 (push/splice)这对 React 识别状态变化至关重要。// ❌ 错误示范 todos.push(newItem); // ✅ 正确示范 (不可变更新) setTodos([...todos, newItem]);4. 项目源码4.1 App.jsximport{useState,useEffect}fromreactimport./styles/app.stylimportTodoListfrom./components/TodoList.jsximportTodoInputfrom./components/TodoInput.jsximportTodoStartsfrom./components/TodoStarts.jsxfunctionApp(){// 子组件共享的数据状态const[todos,setTodos]useState((){// 高级用法constsavedlocalStorage.getItem(todos);returnsaved?JSON.parse(saved):[];});// 子组件修改数据的方法constaddTodo(text){setTodos([...todos,{id:Date.now(),text,completed:false}])}constdeleteTodo(id){setTodos(todos.filter(todotodo.id!id))}consttoggleTodo(id){setTodos(todos.map(todotodo.idid?{...todo,completed:!todo.completed}:todo))}constclearCompleted(){setTodos(todos.filter(todo!todo.completed))}constactiveCounttodos.filter(todo!todo.completed).length;constcompletedCounttodos.filter(todotodo.completed).length;useEffect((){localStorage.setItem(todos,JSON.stringify(todos));},[todos])return(div classNametodo-apph1My Todo List/h1{/* 自定义事件 */}TodoInput onAdd{addTodo}/TodoList todos{todos}onDelete{deleteTodo}onToggle{toggleTodo}/TodoStarts total{todos.length}active{activeCount}completed{completedCount}onClearCompleted{clearCompleted}//div)}exportdefaultApp;4.2 TodoInput.jsximport{useState}fromreactconstTodoInput(props){console.log(props);const{onAdd}props;// react 不支持 Vue 中的 v-model 那样的双向绑定react 认为这样性能不好// react 只支持单向绑定性能好 onChange 实现数据和视图的同步const[inputValue,setInputValue]useState();consthandleSubmit(e){e.preventDefault();onAdd(inputValue);setInputValue();}return(form classNametodo-inputonSubmit{handleSubmit}input typetextvalue{inputValue}onChange{esetInputValue(e.target.value)}/button typesubmitAdd/button/form)}exportdefaultTodoInput;4.3 TodoList.jsxconstTodoList(props){const{todos,onDelete,onToggle}props;return(ul classNametodo-list{todos.length0?(li classNameemptyNo todos yet!/li):(todos.map(todo(li key{todo.id}className{todo.completed?completed:}labelinput typecheckboxchecked{todo.completed}onChange{()onToggle(todo.id)}/span{todo.text}/span/labelbutton onClick{()onDelete(todo.id)}Delete/button/li)))}/ul)}exportdefaultTodoList;4.4 TodoStarts.jsxconstTodoStarts(props){const{total,active,completed,onClearCompleted}props;return(div classNametodo-startspTotal:{total}|Active:{active}|Completed:{completed}/p{completed0(button onClick{onClearCompleted}classNameclear-btnClear Completed/button)}/div)}exportdefaultTodoStarts;
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

前端案例的网站更改wordpress谷歌字体

Zenodo大文件上传完整指南:命令行工具让科研数据共享更简单 【免费下载链接】zenodo-upload upload big files to Zenodo using cURL, jq and bash 项目地址: https://gitcode.com/gh_mirrors/ze/zenodo-upload 还在为Zenodo大文件上传而烦恼吗?传…

张小明 2026/1/8 5:25:41 网站建设

体育西网站开发价格电影下载网站如何做

信号回流路径设计原理:从物理本质到实战落地 你有没有遇到过这样的情况? 电路板明明按数据手册布了线,阻抗也匹配了,等长走线调得一丝不苟,结果一上电——EMI超标、串扰严重、高速链路误码率飙升。反复排查&#xff0…

张小明 2026/1/14 13:45:31 网站建设

建设娱乐城网站做物流的都有哪些网站

据中国基金报报道,某招聘平台显示,杭州深度求索人工智能(AI)基础技术研究有限公司(即DeepSeek),发布了多个岗位的招聘信息。在DeepSeek挂出的职位中,大部分岗位的起薪在3万元以上&am…

张小明 2026/1/8 8:14:17 网站建设

企业网站制作价格wordpress翻译怎么用

BetterNCM插件管理器终极指南:一键解锁音乐播放新体验 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 想要彻底改变网易云音乐的使用体验吗?BetterNCM插件管理器…

张小明 2026/1/9 4:52:04 网站建设

学做漂亮早餐的网站手机网站开发用什么语言

项目速览 【免费下载链接】zotero-reference PDF references add-on for Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-reference Zotero Reference是一款专为学术研究者打造的PDF参考文献智能解析插件,能够自动识别文献中的引用信息&#x…

张小明 2026/1/9 1:37:11 网站建设

阆中网站建设01hl零基础学做网站要多久

清华源 Anaconda 加速 Qwen3-32B 环境搭建:高效部署大模型的实战路径 在当前AI研发节奏日益加快的背景下,一个常见的痛点浮出水面:明明已经选好了像 Qwen3-32B 这样性能强劲的大模型,结果卡在环境配置上——conda install 卡住不…

张小明 2026/1/11 12:30:00 网站建设