目录

一、React入门

1.1 你好React

1.2 创建React

1.3 应用结构

二、总结

2.1 定义组件

2.2 组件源码

三、组件详解

注意事项

3.1 组件三部曲

3.2 组件通信 —— props 

3.3 对象数组迭代 —— map()

3.4 事件处理

3.5 钩子函数 —— useState()

 

初次学习最终效果:

一、React入门

1.1 你好React

熟悉核心 HTML,CSS 和 JavaScript 语言,了解终端/命令行。

        React 使用称为 JSX(JavaScript 和 XML)的 HTML-in-JavaScript 语法。熟悉 HTML 和 JavaScript 可以帮助你学习 JSX,并更好地确定应用程序中的错误是与 JavaScript 还是与 React 的更特定领域相关。

 React 是一个用于构建用户界面的库。React 不是一个框架——它的应用甚至不局限于 Web 开发,它可以与其他库一起使用以渲染到特定环境。

        为了构建 Web 应用,开发人员将 React 与 ReactDOM 结合使用。React 和 ReactDOM 通常被与其他真正的 Web 开发框架相提并论,并用于解决相同的问题。当我们将 React 称为“框架”时,就是在进行口语化的理解。

1.2 创建React

为了使用 create-react-app,你需要安装 Node.js。建议你使用长期支持(LTS)版本。Node 包括 npm(Node 程序包管理器)和 npx(Node 程序包运行器)

可看该篇文章第二节:https://ycxw320.blog.csdn.net/article/details/133101428?spm=1001.2014.3001.5502

一、create-react-app ,该命令接受一个参数:即你想给自己的应用所起的名字。create-react-app 将为此应用创建一个同名的文件夹,并在其中创建所需文件。在你打算放置你的应用程序的文件夹下打开你的命令终端,并键入命令:

npx create-react-app demo-react

 这句命令创建了一个名为 moz-todo-react 的文件夹,并在此文件夹里做了如下工作:

为你的应用程序安装了一些 npm 包;写入 react 应用启动所需要的脚本文件;创建一系列结构化的子文件夹和文件,奠定应用程序的基础架构;如果你的电脑上安装了 git 的话,顺便帮你把 git 仓库也建好。

备注: 如果你的电脑上安装了 yarn 的话,create-react-app 会默认使用 yarn 而非 npm。如果你同时安装了 yarn 和 npm,但你希望使用 npm 的话,在 create-react-app 的时候需要输入 --use-npm :

BASHCopy to Clipboard

npx create-react-app demo-react --use-npm

处理完成之后,你可以 cd 到 demo-react 文件夹下,然后键入 npm start 命令并回车,先前由 create-react-app 创建的脚本会启动一个地服务 localhost:3000,并打开你的默认浏览器来访问这个服务。成功启动浏览器的话,你的浏览器上会显示如下画面:

1.3 应用结构

moz-todo-react

├── README.md

├── node_modules

├── package.json

├── package-lock.json

├── .gitignore

├── public

│ ├── favicon.ico

│ ├── index.html

│ └── manifest.json

└── src

├── App.css

├── App.js

├── App.test.js

├── index.css

├── index.js

├── logo.svg

└── serviceWorker.js

目录 src 是我们花费时间最多的地方,因为它是我们 React 应用源码存放的目录。

目录 public 包含了开发应用时浏览器会读取的文件,其中最重要的就是 index.html。React 将目录 src 中的代码嵌入这个文件,从而浏览器才能运行此文件。 index.html中的有些内容关乎 create-react-app 的运作,因此除非你知道自己在做什么样的修改,否则不建议编辑这个文件。当然,你可以修改index.html中的  元素的内容来表现此应用程序通俗易懂的名称。</p><p>二、总结</p><p>        为什么总结会放在前面呢?因为博主懒,想必学这个的小伙伴也有js与html的基础。在这里我将把所有代码直接放出来,后续再拆分讲解。这样小伙伴们可直接达到最终效果,相比一步一步演示,这样效率更高。同时大家可以自己思考理解,不会再看博客或者ai解释。</p><p> </p><p>2.1 定义组件</p><p>        此时,我们的 App 是一个单体。在我们能使用它之前,我们需要把它分解成可管理的、可描述的组件。React 对于什么是组件和什么不是组件并没有任何硬性规定,这完全取决于你! </p><p>如果它在程序里看起来是个明显的“块”,那它可能是个组件。如果它在程序里经常会被复用,那它可能是个组件。</p><p>第二条很有价值:使用通用的 UI 元素作为组件,可以让你只更改一处,就能更改所有使用该组件的地方。现在你也不必马上把所有东西都拆成组件。让我们从第二点开始做起,将 UI 中重用最多、最重要的部分抽取为一个组件:一个待办事件项。</p><p>如:</p><p>2.2 组件源码</p><p>创建组件文件:</p><p> </p><p>:Form.js</p><p>import React from "react";</p><p>import { useState } from "react";</p><p>/* Form 组件是一个用于添加新任务的表单组件。</p><p>使用 useState 钩子来管理输入框的状态。</p><p>定义了 handleChange 函数来更新输入框中的文本内容,handleSubmit 函数来处理表单的提交事件,以及 addTask 函数来通知父组件添加新任务。</p><p>*/</p><p>function Form(props) {</p><p>const [name, setName] = useState("");</p><p>function handleChange(event) {</p><p>//event.target.value表示输入框当前的值</p><p>setName(event.target.value);</p><p>}</p><p>function handleSubmit(event) {</p><p>event.preventDefault();//阻止表单默认的提交行为,这样页面就不会刷新</p><p>/* 调用了父组件传递过来的 addTask 函数,并将当前输入框中的值 name 作为参数传递给它。</p><p>这样做可以将新的任务名称传递给父组件,用于添加新的任务。 */</p><p>props.addTask(name);</p><p>setName("");</p><p>}</p><p>return (</p><p><form onSubmit={handleSubmit}></p><p><h2 className="label-wrapper"></p><p><label htmlFor="new-todo-input" className="label__lg"></p><p>您 今 天 需 要 做 什 么?</p><p></label></p><p></h2></p><p><input</p><p>type="text"</p><p>id="new-todo-input"</p><p>className="input input__lg"</p><p>name="text"</p><p>autoComplete="off"</p><p>value={name}</p><p>onChange={handleChange}</p><p>/></p><p><button type="submit" className="btn btn__primary btn__lg"></p><p>添加</p><p></button></p><p></form></p><p>);</p><p>}</p><p>export default Form;</p><p>:FilterButton.js</p><p>import React from "react";</p><p>/* FilterButton 组件是一个用于过滤任务列表的按钮组件。</p><p>当点击按钮时,会调用父组件传递过来的 setFilter 函数,从而改变任务列表的过滤条件。*/</p><p>function FilterButton(props) {</p><p>return (</p><p><button</p><p>type="button"</p><p>className="btn toggle-btn"</p><p>aria-pressed={props.isPressed}</p><p>onClick={() => props.setFilter(props.name)}></p><p><span className="visually-hidden">Show </span></p><p><span>{props.name}</span></p><p><span className="visually-hidden"> tasks</span></p><p></button></p><p>);</p><p>}</p><p>export default FilterButton;</p><p>:Todo.js</p><p>import React from "react";</p><p>import { useState } from "react";</p><p>/* Todo 组件用于显示单个任务条目,并提供编辑、删除和切换完成状态的功能。</p><p>使用 useState 钩子来管理编辑状态和新名称的状态。</p><p>根据编辑状态的不同,渲染不同的界面模板,包括查看模板和编辑模板。 */</p><p>export default function Todo(props) {</p><p>const [isEditing, setEditing] = useState(false);</p><p>const [newName, setNewName] = useState("");</p><p>function handleChange(e) {</p><p>setNewName(e.target.value);</p><p>}</p><p>function handleSubmit(e) {</p><p>e.preventDefault();</p><p>props.editTask(props.id, newName);</p><p>setNewName("");</p><p>setEditing(false);</p><p>}</p><p>/* 修改界面*/</p><p>const editingTemplate = (</p><p><form className="stack-small" onSubmit={handleSubmit}></p><p><div className="form-group"></p><p><label className="todo-label" htmlFor={props.id}></p><p>New name for : {props.name}</p><p></label></p><p><input</p><p>id={props.id}</p><p>className="todo-text"</p><p>type="text"</p><p>value={newName}</p><p>onChange={handleChange}</p><p>/></p><p></div></p><p><div className="btn-group"></p><p><button</p><p>type="button"</p><p>className="btn todo-cancel"</p><p>onClick={() => setEditing(false)}></p><p>Cancel</p><p><span className="visually-hidden">renaming {props.name}</span></p><p></button></p><p><button type="submit" className="btn btn__primary todo-edit"></p><p>Save</p><p><span className="visually-hidden">new name for {props.name}</span></p><p></button></p><p></div></p><p></form></p><p>);</p><p>/* 视图界面*/</p><p>const viewTemplate = (</p><p><div className="stack-small"></p><p><div className="c-cb"></p><p><input</p><p>id={props.id}</p><p>type="checkbox"</p><p>defaultChecked={props.completed}</p><p>onChange={() => props.toggleTaskCompleted(props.id)}</p><p>/></p><p><label className="todo-label" htmlFor={props.id}></p><p>{props.name}</p><p></label></p><p></div></p><p><div className="btn-group"></p><p><button type="button" className="btn" onClick={() => setEditing(true)}></p><p>Edit <span className="visually-hidden">{props.name}</span></p><p></button></p><p><button</p><p>type="button"</p><p>className="btn btn__danger"</p><p>onClick={() => props.deleteTask(props.id)}></p><p>Delete <span className="visually-hidden">{props.name}</span></p><p></button></p><p></div></p><p></div></p><p>);</p><p>return <li className="todo">{isEditing ? editingTemplate : viewTemplate}</li>;</p><p>}</p><p>src / App.js:</p><p>import './App.css';</p><p>import Todo from "./components/Todo";</p><p>import Form from "./components/Form";</p><p>import FilterButton from "./components/FilterButton";</p><p>import { useState } from "react";</p><p>import { nanoid } from "nanoid";</p><p>/* App 组件是整个应用的主要组件,它负责渲染整个待办事项列表的界面。</p><p>使用 useState 钩子来管理应用的状态,包括过滤器状态(filter)、任务列表状态(tasks)。</p><p>定义了一些函数来操作任务列表,如添加任务、删除任务、编辑任务、切换任务完成状态。</p><p>渲染了 Form 组件用于添加新任务,FilterButton 组件用于过滤任务列表,以及一系列 Todo 组件用于显示任务条目。</p><p>*/</p><p>function App(props) {</p><p>/* useState()采用确定状态初始值的单个参数。此参数可以是字符串、数字、数组、对象或任何其他 JavaScript 数据类型。</p><p>返回一个包含两个项的数组。第一项是状态的当前值;第二项是可用于更新状态的函数。useState() */</p><p>const [filter, setFilter] = useState("所有"); //初始化任务,默认显示所有</p><p>//过滤器挂钩</p><p>const FILTER_MAP = {</p><p>'所有': () => true,</p><p>'进行': (task) => !task.completed,</p><p>'完成': (task) => task.completed,</p><p>};</p><p>const FILTER_NAMES = Object.keys(FILTER_MAP);</p><p>//交互式过滤器</p><p>const filterList = FILTER_NAMES.map((name) => (</p><p><FilterButton</p><p>key={name}</p><p>name={name}</p><p>isPressed={name === filter}</p><p>setFilter={setFilter}</p><p>/></p><p>));</p><p>// const tasksNoun = taskList.length !== 1 ? "tasks" : "task";</p><p>const [tasks, setTasks] = useState(props.tasks); //事项数据</p><p>//在返回任务之前先筛选任务状态</p><p>const taskList = tasks</p><p>.filter(FILTER_MAP[filter])</p><p>.map((task) => (</p><p><Todo</p><p>id={task.id}</p><p>name={task.name}</p><p>completed={task.completed}</p><p>key={task.id}</p><p>toggleTaskCompleted={toggleTaskCompleted}</p><p>deleteTask={deleteTask}</p><p>editTask={editTask}</p><p>/></p><p>));</p><p>const headingText = `${taskList.length} 任务 剩余`; //计数</p><p>function addTask(name) {</p><p>const newTask = { id: `todo-${nanoid()}`, name, completed: false };</p><p>setTasks([...tasks, newTask]);</p><p>}</p><p>function deleteTask(id) {</p><p>//如果一个任务的 prop 与传入的参数匹配,则从新数组中排除这个个任务。</p><p>const remainingTasks = tasks.filter((task) => id !== task.id);</p><p>setTasks(remainingTasks);</p><p>}</p><p>function editTask(id, newName) {</p><p>const editedTaskList = tasks.map((task) => {</p><p>// 判断需要修改的id事项</p><p>if (id === task.id) {</p><p>// 将该id的事项名更改为新的名字</p><p>return { ...task, name: newName };</p><p>}</p><p>// 否则返回原对象</p><p>return task;</p><p>});</p><p>setTasks(editedTaskList);</p><p>}</p><p>function toggleTaskCompleted(id) {</p><p>const updatedTasks = tasks.map((task) => {</p><p>// 如果此任务与编辑的任务具有相同的 ID</p><p>if (id === task.id) {</p><p>// 使用对象扩展创建新对象</p><p>return { ...task, completed: !task.completed };</p><p>}</p><p>return task;</p><p>});</p><p>setTasks(updatedTasks);</p><p>}</p><p>return (</p><p><div className="todoapp stack-large"></p><p><h1>待办事项列表</h1></p><p><Form addTask={addTask}/></p><p><div className="filters btn-group stack-exception"></p><p>{filterList}</p><p></div></p><p><h3 id="list-heading">{headingText}</h3></p><p><ul</p><p>role="list"</p><p>className="todo-list stack-large stack-exception"</p><p>aria-labelledby="list-heading"></p><p>{taskList}</p><p></ul></p><p></div></p><p>);</p><p>}</p><p>export default App;</p><p>src / index.js:</p><p>import React from 'react';</p><p>import ReactDOM from 'react-dom/client';</p><p>import './index.css';</p><p>import App from './App';</p><p>/* index.js 是应用的入口文件,负责将 App 组件渲染到页面上。</p><p>使用 ReactDOM.createRoot 方法创建根节点,然后调用 root.render 将 App 组件渲染到根节点上。</p><p>定义了一个名为 DATA 的常量,包含了初始的任务数据,然后将这个数据作为 tasks 属性传递给 App 组件。*/</p><p>/* 默认列表参数 */</p><p>const DATA = [</p><p>{ id: "todo-0", name: "学习React", completed: true },</p><p>{ id: "todo-1", name: "调整作息习惯", completed: false },</p><p>{ id: "todo-2", name: "好好吃饭,锻炼身体", completed: false },</p><p>];</p><p>/* 根据指定容器创建React对象 */</p><p>const root = ReactDOM.createRoot(document.getElementById('root'));</p><p>root.render(</p><p><App tasks={DATA} /></p><p>);</p><p>src / index.css:</p><p>/* RESETS */</p><p>*,</p><p>*::before,</p><p>*::after {</p><p>box-sizing: border-box;</p><p>}</p><p>*:focus {</p><p>outline: 3px dashed #228bec;</p><p>outline-offset: 0;</p><p>}</p><p>html {</p><p>font: 62.5% / 1.15 sans-serif;</p><p>}</p><p>h1,</p><p>h2 {</p><p>margin-bottom: 0;</p><p>}</p><p>ul {</p><p>list-style: none;</p><p>padding: 0;</p><p>}</p><p>button {</p><p>border: none;</p><p>margin: 0;</p><p>padding: 0;</p><p>width: auto;</p><p>overflow: visible;</p><p>background: transparent;</p><p>color: inherit;</p><p>font: inherit;</p><p>line-height: normal;</p><p>-webkit-font-smoothing: inherit;</p><p>-moz-osx-font-smoothing: inherit;</p><p>-webkit-appearance: none;</p><p>}</p><p>button::-moz-focus-inner {</p><p>border: 0;</p><p>}</p><p>button,</p><p>input,</p><p>optgroup,</p><p>select,</p><p>textarea {</p><p>font-family: inherit;</p><p>font-size: 100%;</p><p>line-height: 1.15;</p><p>margin: 0;</p><p>}</p><p>button,</p><p>input {</p><p>overflow: visible;</p><p>}</p><p>input[type="text"] {</p><p>border-radius: 0;</p><p>}</p><p>body {</p><p>width: 100%;</p><p>max-width: 68rem;</p><p>margin: 0 auto;</p><p>font:</p><p>1.6rem/1.25 Arial,</p><p>sans-serif;</p><p>background-color: #f5f5f5;</p><p>color: #4d4d4d;</p><p>}</p><p>@media screen and (min-width: 620px) {</p><p>body {</p><p>font-size: 1.9rem;</p><p>line-height: 1.31579;</p><p>}</p><p>}</p><p>/*END RESETS*/</p><p>/* GLOBAL STYLES */</p><p>.form-group > input[type="text"] {</p><p>display: inline-block;</p><p>margin-top: 0.4rem;</p><p>}</p><p>.btn {</p><p>padding: 0.8rem 1rem 0.7rem;</p><p>border: 0.2rem solid #4d4d4d;</p><p>cursor: pointer;</p><p>text-transform: capitalize;</p><p>}</p><p>.btn.toggle-btn {</p><p>border-width: 1px;</p><p>border-color: #d3d3d3;</p><p>}</p><p>.btn.toggle-btn[aria-pressed="true"] {</p><p>text-decoration: underline;</p><p>border-color: #4d4d4d;</p><p>}</p><p>.btn__danger {</p><p>color: #fff;</p><p>background-color: #ca3c3c;</p><p>border-color: #bd2130;</p><p>}</p><p>.btn__filter {</p><p>border-color: lightgrey;</p><p>}</p><p>.btn__primary {</p><p>color: #fff;</p><p>background-color: #000;</p><p>}</p><p>.btn-group {</p><p>display: flex;</p><p>justify-content: space-between;</p><p>}</p><p>.btn-group > * {</p><p>flex: 1 1 49%;</p><p>}</p><p>.btn-group > * + * {</p><p>margin-left: 0.8rem;</p><p>}</p><p>.label-wrapper {</p><p>margin: 0;</p><p>flex: 0 0 100%;</p><p>text-align: center;</p><p>}</p><p>.visually-hidden {</p><p>position: absolute !important;</p><p>height: 1px;</p><p>width: 1px;</p><p>overflow: hidden;</p><p>clip: rect(1px 1px 1px 1px);</p><p>clip: rect(1px, 1px, 1px, 1px);</p><p>white-space: nowrap;</p><p>}</p><p>[class*="stack"] > * {</p><p>margin-top: 0;</p><p>margin-bottom: 0;</p><p>}</p><p>.stack-small > * + * {</p><p>margin-top: 1.25rem;</p><p>}</p><p>.stack-large > * + * {</p><p>margin-top: 2.5rem;</p><p>}</p><p>@media screen and (min-width: 550px) {</p><p>.stack-small > * + * {</p><p>margin-top: 1.4rem;</p><p>}</p><p>.stack-large > * + * {</p><p>margin-top: 2.8rem;</p><p>}</p><p>}</p><p>.stack-exception {</p><p>margin-top: 1.2rem;</p><p>}</p><p>/* END GLOBAL STYLES */</p><p>.todoapp {</p><p>background: #fff;</p><p>margin: 2rem 0 4rem 0;</p><p>padding: 1rem;</p><p>position: relative;</p><p>box-shadow:</p><p>0 2px 4px 0 rgba(0, 0, 0, 0.2),</p><p>0 2.5rem 5rem 0 rgba(0, 0, 0, 0.1);</p><p>}</p><p>@media screen and (min-width: 550px) {</p><p>.todoapp {</p><p>padding: 4rem;</p><p>}</p><p>}</p><p>.todoapp > * {</p><p>max-width: 50rem;</p><p>margin-left: auto;</p><p>margin-right: auto;</p><p>}</p><p>.todoapp > form {</p><p>max-width: 100%;</p><p>}</p><p>.todoapp > h1 {</p><p>display: block;</p><p>max-width: 100%;</p><p>text-align: center;</p><p>margin: 0;</p><p>margin-bottom: 1rem;</p><p>}</p><p>.label__lg {</p><p>line-height: 1.01567;</p><p>font-weight: 300;</p><p>padding: 0.8rem;</p><p>margin-bottom: 1rem;</p><p>text-align: center;</p><p>}</p><p>.input__lg {</p><p>padding: 2rem;</p><p>border: 2px solid #000;</p><p>}</p><p>.input__lg:focus {</p><p>border-color: #4d4d4d;</p><p>box-shadow: inset 0 0 0 2px;</p><p>}</p><p>[class*="__lg"] {</p><p>display: inline-block;</p><p>width: 100%;</p><p>font-size: 1.9rem;</p><p>}</p><p>[class*="__lg"]:not(:last-child) {</p><p>margin-bottom: 1rem;</p><p>}</p><p>@media screen and (min-width: 620px) {</p><p>[class*="__lg"] {</p><p>font-size: 2.4rem;</p><p>}</p><p>}</p><p>.filters {</p><p>width: 100%;</p><p>margin: unset auto;</p><p>}</p><p>/* Todo item styles */</p><p>.todo {</p><p>display: flex;</p><p>flex-direction: row;</p><p>flex-wrap: wrap;</p><p>}</p><p>.todo > * {</p><p>flex: 0 0 100%;</p><p>}</p><p>.todo-text {</p><p>width: 100%;</p><p>min-height: 4.4rem;</p><p>padding: 0.4rem 0.8rem;</p><p>border: 2px solid #565656;</p><p>}</p><p>.todo-text:focus {</p><p>box-shadow: inset 0 0 0 2px;</p><p>}</p><p>/* CHECKBOX STYLES */</p><p>.c-cb {</p><p>box-sizing: border-box;</p><p>font-family: Arial, sans-serif;</p><p>-webkit-font-smoothing: antialiased;</p><p>font-weight: 400;</p><p>font-size: 1.6rem;</p><p>line-height: 1.25;</p><p>display: block;</p><p>position: relative;</p><p>min-height: 44px;</p><p>padding-left: 40px;</p><p>clear: left;</p><p>}</p><p>.c-cb > label::before,</p><p>.c-cb > input[type="checkbox"] {</p><p>box-sizing: border-box;</p><p>top: -2px;</p><p>left: -2px;</p><p>width: 44px;</p><p>height: 44px;</p><p>}</p><p>.c-cb > input[type="checkbox"] {</p><p>-webkit-font-smoothing: antialiased;</p><p>cursor: pointer;</p><p>position: absolute;</p><p>z-index: 1;</p><p>margin: 0;</p><p>opacity: 0;</p><p>}</p><p>.c-cb > label {</p><p>font-size: inherit;</p><p>font-family: inherit;</p><p>line-height: inherit;</p><p>display: inline-block;</p><p>margin-bottom: 0;</p><p>padding: 8px 15px 5px;</p><p>cursor: pointer;</p><p>touch-action: manipulation;</p><p>}</p><p>.c-cb > label::before {</p><p>content: "";</p><p>position: absolute;</p><p>border: 2px solid currentcolor;</p><p>background: transparent;</p><p>}</p><p>.c-cb > input[type="checkbox"]:focus + label::before {</p><p>border-width: 4px;</p><p>outline: 3px dashed #228bec;</p><p>}</p><p>.c-cb > label::after {</p><p>box-sizing: content-box;</p><p>content: "";</p><p>position: absolute;</p><p>top: 11px;</p><p>left: 9px;</p><p>width: 18px;</p><p>height: 7px;</p><p>transform: rotate(-45deg);</p><p>border: solid;</p><p>border-width: 0 0 5px 5px;</p><p>border-top-color: transparent;</p><p>opacity: 0;</p><p>background: transparent;</p><p>}</p><p>.c-cb > input[type="checkbox"]:checked + label::after {</p><p>opacity: 1;</p><p>}</p><p>创建唯一标识符分开不同任务,JavaScript 社区为此编写了一些有用的库。我们将使用 nanoid,因为它很小而且有效。</p><p>请确保位于应用程序的根目录中,并运行以下终端命令:</p><p>npm install nanoid</p><p>三、组件详解</p><p>注意事项</p><p>        以下的讲解会更源码有所不同,因为源码是经过以下简单的示例中演变而来的,你只需要关注属性如何定义、传值和组件如何交互即可。</p><p>3.1 组件三部曲</p><p>第一步:导入 React 库中的 react 模块</p><p>import React from "react";</p><p>在使用 JSX 语法时,需要引入 React 库,因为 JSX 实际上被转译为对 React.createElement() 方法的调用。在 React 应用中,通常需要在每个组件文件的开头导入 React,以便使用 React 的相关功能。</p><p>第二步:添加组件内容</p><p>既然我们要做一个叫做 (例:Todo) 的组件,就要在 Todo.js 中加入相关代码。如下所示,这段代码中,我们使用了一行代码定义了函数并导出了它。 </p><p>export default function Todo() {</p><p>return (</p><p>// Html内容</p><p>);</p><p>}</p><p>备注: 组件必须返回一些东西。如果你试图渲染一个不返回任何东西的组件,React 会在浏览器中提示出现错误。</p><p> </p><p>第三步: 使用组件</p><p>在 App.js 中,在文件顶部添加以下代码,导入组件:</p><p>import Todo from "./components/Todo";</p><p>import Form from "./components/Form";</p><p>import FilterButton from "./components/FilterButton";</p><p>导入组件之后,你可以调用 <Todo(Form、FilterButton) /> 组件来展示内容。</p><p> </p><p>3.2 组件通信 —— props </p><p>        在 React 中,组件之间通信主要通过属性(props)来实现。props 是从父组件传递给子组件的数据,它可以是任何类型的数据,包括字符串、数字、对象、函数等。在组件内部,可以通过 props 来访问这些数据,以便在组件中进行渲染或执行其他操作。</p><p>1、在 App.js 中,给每个 <Todo /> 传递一个 name prop: </p><p><Todo name="学习React" /></p><p><Todo name="吃饭" /></p><p><Todo name="睡觉" /></p><p>2、首先修改 Todo() 函数定义,使其接受 props 参数。如果你想检查 props 是否被组件正确接收,你可以像之前那样使用 console.log() 检查你的 props。</p><p>export default function Todo(props) {</p><p>return (</p><p><label className="todo-label" htmlFor="todo-0"></p><p>{props.name}</p><p></label></p><p>);</p><p>}</p><p>在index.js中我已经定义好默认的三个组件信息:</p><p>后续数据就可以调用接口来赋值;</p><p>3、渲染到页面容器</p><p>可以看到index.js:</p><p>const root = ReactDOM.createRoot(document.getElementById('root'));</p><p>root.render(</p><p><App tasks={DATA} /></p><p>);</p><p> 这段代码是 React 渲染流程的关键部分,它的作用是将根组件 App 渲染到页面上的特定容器中。</p><p>1、ReactDOM.createRoot(document.getElementById('root')):</p><p>ReactDOM 是 React 库中用于操作 DOM 的模块。createRoot 是 ReactDOM 提供的一个方法,用于创建一个 React 根对象。document.getElementById('root') 是获取页面中 id 为 'root(index.html)' 的 DOM 元素,这是一个容器,我们希望将 React 应用渲染到这个容器中。</p><p>2、const root = ReactDOM.createRoot(document.getElementById('root')):</p><p>这一行代码将创建的 React 根对象赋值给名为 root 的常量,以便后续的操作。</p><p>3、root.render(<App tasks={DATA} />):</p><p>root.render() 方法用于将 React 组件渲染到页面上。<App tasks={DATA} /> 是要渲染的 React 组件,即根组件 App。这里通过 JSX 语法将 App 组件以及它的属性 tasks 传递给 root.render() 方法。{DATA} 是一个包含初始任务数据的数组,作为 tasks 属性传递给 App 组件。</p><p>3.3 对象数组迭代 —— map()</p><p>        在 return 语句的上方,新建一个叫 taskList 的 const,然后使用 map() 去转换它。我们先把 tasks 数组变成简单的东西:每个任务的 name:</p><p>const taskList = props.tasks?.map((task) => task.name);</p><p> </p><p>这样能获取到了每个组件的name值了,那如何遍历到不同的组件中呢? 记住 JSX 允许我们将 JavaScript 和标记结构混合起来!让我们用下面的方法替代已有的试试</p><p>如App.js:</p><p>const taskList = tasks.map((task) => (</p><p><Todo</p><p>id={task.id}</p><p>name={task.name}</p><p>completed={task.completed}</p><p>key={task.id}</p><p>/></p><p>));</p><p>        现在 React 正在将我们的任务从一个数组中渲染出来,它必须跟踪谁是谁,以便正确的渲染它们。React 通过自行猜测来保持对每一项的追踪,不过我们通过给 <Todo /> 传递一个 key prop 来帮助 React 保持追踪。key 是一个被 React 管理的特殊的 prop,你不能将其用于其他目的。</p><p>        因为每个 key 必须是不同的(),我们复用每个任务对象的 id 属性来作为它的 key。</p><p>3.4 事件处理</p><p>        普通的 JavaScript需要查询一些 DOM 节点并将侦听器附加到它们。在 JSX 中,描述 UI 的代码与我们的事件侦听器并存:</p><p>在此示例中,我们将向 <button> 元素添加一个属性。该属性的值是触发简单警报的函数。</p><p><button type="button" onClick={() => alert("hi!")}></p><p>Say hi!</p><p></button></p><p>该属性在这里具有特殊的含义:它告诉 React 在用户单击按钮时运行给定的函数。还有其他几点需要注意:onClick</p><p>骆驼大小写的性质很重要——JSX 不会识别.所有浏览器事件都遵循 JSX – 中的这种格式,on 后跟事件的名称。</p><p>让我们从组件开始将其应用于我们的应用程序:Form.js</p><p>通过回调处理表单提交</p><p>在函数中,创建一个名为 addTask(后续用来添加事项的)的函数:App.js</p><p>function addTask(name) {</p><p>alert(name);</p><p>}</p><p>接下来,作为道具传递。</p><p>最后,我们可以在组件的函数中使用这个道具了!Form.js:</p><p>function handleSubmit(event) {</p><p>event.preventDefault();</p><p>props.addTask("Say hello!");</p><p>}</p><p>3.5 钩子函数 —— useState()</p><p>        到目前为止,我们已经使用道具通过我们的组件传递数据。但是,现在我们正在处理交互性,我们需要能够创建新数据,保留数据并在以后更新数据。道具不是这项工作的正确工具,因为它们是不可变的——组件不能更改或创建自己的道具。</p><p>        这就是状态的用武之地。如果我们将道具视为组件之间通信的一种方式,那么我们可以将状态视为一种赋予组件“内存”的方式——它们可以保留并根据需要更新的信息。</p><p>React 提供了一个特殊的函数,用于将状态引入组件,恰如其分地命名为 。useState()</p><p>import { useState } from "react";</p><p>让我们创建一个状态。在函数上方写下以下内容(一般默认useState(" ")):</p><p>const [name, setName] = useState("Learn React");</p><p>这行代码中发生了几件事:</p><p>我们正在定义一个值为 的常量。name="Learn React"我们正在定义一个函数,其工作是修改 ,称为 。setName()useState()在数组中返回这两个内容,因此我们使用数组解构来在单独的变量中捕获它们。</p><p>Form.js: </p><p> 最后读取输入框的值更新数据:</p><p>function handleChange(event) {</p><p>//event.target.value表示输入框当前的值</p><p>setName(event.target.value);</p><p>}</p><p>详情参考文章:Getting started with React</p><p>相关阅读</p><div class="ly_isview_code_1"><div class="ly_isview_codea" data-id="18747240"><span><a href="https://www.51969.com/zb_system/login.php" target="_blank">评论可见</a>,请评论后查看内容,谢谢!!!</span></div></div><!-- 统计访客停留时间 --><div id="tingliu" style="background-color:#FFFFFF;border:1px dashed #FF0000;text-align:center;display:block;"><span class="tingliu2 hint--top hint--bounce"><a href="##read_time"><img src="https://www.51969.com/zb_users/plugin/zharry_Reading_time/images/tishi.gif" class="tingliu5" ></a></span>  <span class="tingliu2">您阅读本篇文章共花了:</span> <span class="tingliu3" id="stime"></span> </div></br><!-- 统计访客停留时间结束 --><script language="JavaScript">var ss=0,mm=0,hh=0;function TimeGo(){ss++;if(ss>=60){mm+=1;ss=0}if(mm>=60){hh+=1;mm=0}ss_str=(ss<10?"0"+ss:ss);mm_str=(mm<10?"0"+mm:mm);tMsg=""+hh+"小时"+mm_str+"分"+ss_str+"秒";document.getElementById("stime").innerHTML=tMsg;setTimeout("TimeGo()",1000)}TimeGo();</script> </div> <div class="tags"> <a href="https://www.51969.com/tags/react.js/" target="_blank">react.js</a><a href="https://www.51969.com/tags/javascript/" target="_blank">javascript</a><a href="https://www.51969.com/tags/%E5%89%8D%E7%AB%AF/" target="_blank">前端</a><a href="https://www.51969.com/tags/npm/" target="_blank">npm</a> </div> <div class="copyright"><blockquote>本文由 用户 于 2024-05-06 发布在 金钥匙,如有疑问,请联系我们。<br>本文链接:<a href="https://www.51969.com/post/18747240.html">https://www.51969.com/post/18747240.html</a></blockquote></div> <div class="single-share"> <div class="post-share"> <a title="分享"><i class="jzicon-jzfenxiang"></i></a> <div class="share-icons share-sns" data-title="react.js javascript 前端 npm 设置你的第一个React应用" data-url="https://www.51969.com/post/18747240.html"> <span class="share-icon share-wechat cl" data-type="wechat" title="分享到微信"><i class="jzicon-weixin"></i><span id="wechat-qrcode"></span></span> <span class="share-icon share-sina-weibo cl" data-type="weibo" title="分享到微博"><i class="jzicon-weibo"></i></span><span class="share-icon share-qq cl" data-type="qq" title="分享到QQ好友"><i class="jzicon-qq"></i></span> </div> </div> <div class="post-like"> <a href="javascript:;" onclick="Jz52_tsqa_prise('18747240')" class="Jz52_tsqa_prise_id-18747240 dotGood Jz52_tsqa_prise badge" title="好文!一定要点赞!" data-badge="0"><i class="jzicon-jzzan-h"></i><em class="emz">0</em><em>赞</em></a><a href="javascript:;" class="comiis_poster_a single_icon bill_icon" title="文章海报"><i class="jzicon-jzimg"></i></a> </div></div> </div> <div class="nextpro www_51969_com"> <div class="prev"> <article class="post-overlay"> <div class="background-img" style="background-image:url(https://www.51969.com/zb_users/theme/Jz52_tsqa/style/images/prevnoimg.jpg)"> </div> <div class="post_text"> <span><i class="jzicon-angle-left"></i>上一篇</span> <h3 class="post__title typescale-1 nav-prev">开发语言 Rust-模式匹配:简洁、可读,完备</h3> </div> <a href="https://www.51969.com/post/18747233.html" class="link-overlay"></a> </article> </div> <div class="next"> <article class="post-overlay"> <div class="background-img" style="background-image:url(https://www.51969.com/zb_users/theme/Jz52_tsqa/style/images/nextnoimg.jpg)"> </div> <div class="post_text"> <span>下一篇<i class="jzicon-angle-right"></i></span> <h3 class="post__title typescale-1 nav-next">react.js javascript 前端 从0到1,带你深入了解react fiber</h3> </div> <a href="https://www.51969.com/post/18747247.html" class="link-overlay"></a> </article> </div> </div> <div class="related-list www_51969_com"> <h3><i class="jzicon-jztuwen"></i> 相关文章</h3> <ul> <li><a href="https://www.51969.com/post/18790703.html" title="javascript vue.js html5 css3 typescript 前端Vue uni-app中的通用网络请求封装:common.js的使用"><p>javascript vue.js html5 css3 typescript 前端Vue uni-app中的通用网络请求封装:common.js的使用</p></a> </li> <li><a href="https://www.51969.com/post/18790689.html" title="javascript vue.js 音视频 vue项目中定制化音频展示,wavesurfer.js基本使用"><p>javascript vue.js 音视频 vue项目中定制化音频展示,wavesurfer.js基本使用</p></a> </li> <li><a href="https://www.51969.com/post/18790192.html" title="前端 Python面试题大全(三):Web开发(Flask、爬虫)"><p>前端 Python面试题大全(三):Web开发(Flask、爬虫)</p></a> </li> <li><a href="https://www.51969.com/post/18789688.html" title="react.js javascript React Native 框架开发的APP代码 发布为APK文件,实现手机端可安装 步骤详解,配图文"><p>react.js javascript React Native 框架开发的APP代码 发布为APK文件,实现手机端可安装 步骤详解,配图文</p></a> </li> <li><a href="https://www.51969.com/post/18790675.html" title="算法 华为机试 JavaScript C语言 华为OD机试 - 员工派遣(Java & JS & Python & C & C++)"><p>算法 华为机试 JavaScript C语言 华为OD机试 - 员工派遣(Java & JS & Python & C & C++)</p></a> </li> <li><a href="https://www.51969.com/post/18790325.html" title="前端 HBuilderX配置外部服务器(tomcat)查看编辑jsp界面"><p>前端 HBuilderX配置外部服务器(tomcat)查看编辑jsp界面</p></a> </li> <li><a href="https://www.51969.com/post/18789702.html" title="react.js [译] React Native 对 Flutter:哪一个对创业公司更加友好?"><p>react.js [译] React Native 对 Flutter:哪一个对创业公司更加友好?</p></a> </li> <li><a href="https://www.51969.com/post/18789667.html" title="react.js javascript React Native简介和环境配置,差点挂在第四面"><p>react.js javascript React Native简介和环境配置,差点挂在第四面</p></a> </li> </ul> </div> <div class="comments www_51969_com"> <div id="comments" class="comments-area clearfix"> <div class="comment-list"><!--评论框--><div class="jz-comment" id="divCommentPost"><h4 class="comments-title"> <span><i class="jzicon-jzqipaoc"></i>发表评论</span><a rel="nofollow" id="cancel-reply" href="#divCommentPost" style="display:none;float:right;"><small>取消回复</small></a></h4> <form id="frmSumbit" target="_self" method="post" action="https://www.51969.com/zb_system/cmd.php?act=cmt&postid=18747240&key=f3975b7f4fe15fb47404bef4df3daed6" ><input type="hidden" name="inpId" id="inpId" value="18747240"><input type="hidden" name="inpRevID" id="inpRevID" value="0"><div class="jz-comment-box jz-comment-ul3"> <input type="text" name="inpName" id="inpName" class="text" value="" size="28" tabindex="1" placeholder="名称(*)"> </div> <div class="jz-comment-box jz-comment-ul3 jz-comment-ul3-2"> <input type="text" name="inpEmail" id="inpEmail" class="text" value="" size="28" tabindex="2" placeholder="邮箱"> </div> <div class="jz-comment-box jz-comment-ul3"> <input type="text" name="inpHomePage" id="inpHomePage" class="text" value="" size="28" tabindex="3" placeholder="网站"> </div><div class="jz-comment-box jz-comment-textarea"> <textarea name="txaArticle" id="txaArticle" class="text" cols="50" rows="4" tabindex="5" placeholder="欢迎在这里交流评论,但是垃圾评论不受欢迎!"></textarea> </div><input name="sumbit" type="submit" tabindex="6" value="发表评论" onclick="return zbp.comment.post()" class="jz-commbut"> </form></div><label id="AjaxCommentBegin"></label><!--评论输出--><!--评论翻页条输出--><div class="pagelist page-comment"> </div><label id="AjaxCommentEnd"></label></div> </div></div> </div> </div> <aside id="sticky-wrapper"><div> <span class="ifread"><a href="javascript:;" onclick="Jz52_tsqa_prise('18747240')" class="Jz52_tsqa_prise_id-18747240 dotGood Jz52_tsqa_prise badge" title="好文!一定要点赞!" data-badge="0"><i class="jzicon-jzzan-h"></i><em class="emz">0</em><em>赞</em></a></span><span class="ifread"><a title="回复" href="#divCommentPost" class="badge" data-badge="0"><i class="jzicon-message-3-fill"></i></a></span><span class="ifread"><a title="热度" href="#" class="badge" data-badge="5"><i class="jzicon-fire-fill"></i></a></span><span class="ifread Cshare"><a title="分享" href="javascript:;" class=""><i class="jzicon-share-forward-fill"></i></a> <em class="share-sns" data-title="react.js javascript 前端 npm 设置你的第一个React应用" data-url="https://www.51969.com/post/18747240.html"> <span class="cl" data-type="wechatl" title="分享到微信"><a title="分享到微信" href="#" class="bds_weixin" ><i class="jzicon-weixin"></i>微信<span id="wechat-qrcodel"></span></a></span><span class="cl" data-type="weibo" title="分享到微博"><a title="分享到新浪微博" href="#" class="bds_tsina" ><i class="jzicon-weibo"></i>新浪微博</a></span><span class="cl" data-type="qzone" title="分享到QQ空间"><a title="分享到QQ空间" href="#" class="bds_qzone" ><i class="jzicon-qzone"></i>QQ空间</a></span><span class="cl" data-type="qq" title="分享到QQ好友"><a title="分享到QQ好友" href="#" class="bds_qq" ><i class="jzicon-qq"></i>QQ</a></span> </em></span><span style="margin-top: 30px;"><a href="javascript:;" title="沉浸阅读" class="goread"><i class="jzicon-book-read-fill"></i></a></span></div></aside> <aside id="sidebar-right"><div class="widget ifread" id="side-new-userarticle"><h3 class="function_t">TA的新帖</h3><ul><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"><a class="list-title" href="https://www.51969.com/post/18741094.html" target="_blank" title="python AI赋能智能交通:人工智能如何改善交通流量管理和道路安全?">python AI赋能智能交通:人工智能如何改善交通流量管理和道路安全?</a></div><div class="list-footer"><span>2024-05-07</span></div></div><div class="clear"></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"><a class="list-title" href="https://www.51969.com/post/18747240.html" target="_blank" title="react.js javascript 前端 npm 设置你的第一个React应用">react.js javascript 前端 npm 设置你的第一个React应用</a></div><div class="list-footer"><span>2024-05-06</span></div></div><div class="clear"></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"><a class="list-title" href="https://www.51969.com/post/18835769.html" target="_blank" title="人工智能 机器学习 深度学习与神经网络:强化学习">人工智能 机器学习 深度学习与神经网络:强化学习</a></div><div class="list-footer"><span>2024-05-04</span></div></div><div class="clear"></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"><a class="list-title" href="https://www.51969.com/post/18579163.html" target="_blank" title="javascript 前端 开发语言 判断两个数组相等 数组比较 js数组比较 Js如何判断两个数组是否相等?">javascript 前端 开发语言 判断两个数组相等 数组比较 js数组比较 Js如何判断两个数组是否相等?</a></div><div class="list-footer"><span>2024-05-04</span></div></div><div class="clear"></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"><a class="list-title" href="https://www.51969.com/post/18796156.html" target="_blank" title="运维 【windows】--- nginx 超详细安装并配置教程">运维 【windows】--- nginx 超详细安装并配置教程</a></div><div class="list-footer"><span>2024-05-03</span></div></div><div class="clear"></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"><a class="list-title" href="https://www.51969.com/post/18832717.html" target="_blank" title="pycharm 新手学Python用什么编辑器比较好?">pycharm 新手学Python用什么编辑器比较好?</a></div><div class="list-footer"><span>2024-05-03</span></div></div><div class="clear"></div></li></ul></div><div id="directory"></div><div class="widget ifread www_51969_com" id="divSearchPanel"><h3 class="function_t">搜索</h3><div><form name="search" method="post" action="https://www.51969.com/zb_system/cmd.php?act=search"><input type="text" name="q" size="11" /> <input type="submit" value="搜索" /></form></div></div><div class="widget ifread www_51969_com" id="side-hot-view-item"><h3 class="function_t">热门文章</h3><ul><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15795466.html" target="_blank" title="开发语言 【Python】通过第三方库wxauto自动化操作微信电脑客户端">开发语言 【Python】通过第三方库wxauto自动化操作微信电脑客户端</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15782375.html" target="_blank" title="python Django web开发(一) - 前端">python Django web开发(一) - 前端</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/1359046.html" target="_blank" title="vue.js elementui 前端 vue中PC端使用高德地图 -- 实现搜索定位、地址标记、弹窗显示定位详情">vue.js elementui 前端 vue中PC端使用高德地图 -- 实现搜索定位、地址标记、弹窗显示定位详情</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/18610901.html" target="_blank" title="windows 强烈推荐!!一款TCP/UDP Socket 测试工具">windows 强烈推荐!!一款TCP/UDP Socket 测试工具</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/18137843.html" target="_blank" title="深度学习 一文精简介绍CNN神经网络">深度学习 一文精简介绍CNN神经网络</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/13760144.html" target="_blank" title="网络安全 学习 AI编程 copilot 【网安AIGC专题】46篇前沿代码大模型论文、24篇论文阅读笔记汇总">网络安全 学习 AI编程 copilot 【网安AIGC专题】46篇前沿代码大模型论文、24篇论文阅读笔记汇总</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15791529.html" target="_blank" title="linux 解决Error while loading conda entry point: conda-libmamba-solver (libarchive.so.19: cannot open shared">linux 解决Error while loading conda entry point: conda-libmamba-solver (libarchive.so.19: cannot open shared</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/157861.html" target="_blank" title="ide 编辑器 VSCode 安装教程(超详细)">ide 编辑器 VSCode 安装教程(超详细)</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15798461.html" target="_blank" title="linux 运维 ubuntu 安装jdk21开发环境">linux 运维 ubuntu 安装jdk21开发环境</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15789783.html" target="_blank" title="一键解决json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)">一键解决json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)</a> </div><div class="list-footer"> <span>2024-05-06</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/13768174.html" target="_blank" title="python 开发语言 Stable Diffusion 本地部署教程">python 开发语言 Stable Diffusion 本地部署教程</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/157442.html" target="_blank" title="Amazon CodeWhisperer 免费 AI 代码生成助手体验分享">Amazon CodeWhisperer 免费 AI 代码生成助手体验分享</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15789774.html" target="_blank" title="路由跳转 GetPage使用详情 Getx使用详情 Flutter中GetX系列九--路由/页面跳转,传值,中间件(GetPage)">路由跳转 GetPage使用详情 Getx使用详情 Flutter中GetX系列九--路由/页面跳转,传值,中间件(GetPage)</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15782324.html" target="_blank" title="分布式 EFAK kafka安装 上手第一关,手把手教你安装kafka与可视化工具kafka-eagle">分布式 EFAK kafka安装 上手第一关,手把手教你安装kafka与可视化工具kafka-eagle</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/157419.html" target="_blank" title="前端 后端 开发语言 华为云 【华为鸿蒙系统学习】- HarmonyOS4.0开发|自学篇">前端 后端 开发语言 华为云 【华为鸿蒙系统学习】- HarmonyOS4.0开发|自学篇</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/17822463.html" target="_blank" title="开发语言 Java 19的未来:新特性、性能优化和更多">开发语言 Java 19的未来:新特性、性能优化和更多</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15791813.html" target="_blank" title="selenium java chrome 【软件测试】单元测试工具---Junit详解">selenium java chrome 【软件测试】单元测试工具---Junit详解</a> </div><div class="list-footer"> <span>2024-05-06</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/157659.html" target="_blank" title="c语言 ide 编辑器 vscode配置C/C++环境(超详细保姆级教学)">c语言 ide 编辑器 vscode配置C/C++环境(超详细保姆级教学)</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/18664703.html" target="_blank" title="【AIGC调研系列】通义灵码与copilot的对比">【AIGC调研系列】通义灵码与copilot的对比</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15782501.html" target="_blank" title="Nacos Consul 服务发现 服务治理 Dubbo引入Zookeeper等注册中心简介以及DubboAdmin简要介绍,为后续详解Dubbo各种注册中心做铺垫!">Nacos Consul 服务发现 服务治理 Dubbo引入Zookeeper等注册中心简介以及DubboAdmin简要介绍,为后续详解Dubbo各种注册中心做铺垫!</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15786567.html" target="_blank" title="网络安全 人工智能 ai 指纹识别工具WhatWeb使用教程,图文教程(超详细)">网络安全 人工智能 ai 指纹识别工具WhatWeb使用教程,图文教程(超详细)</a> </div><div class="list-footer"> <span>2024-05-06</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15786708.html" target="_blank" title="开发语言 MATLAB R2022b 安装教程">开发语言 MATLAB R2022b 安装教程</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15782925.html" target="_blank" title="运维 Linux系统下安装配置 Nginx 超详细图文教程">运维 Linux系统下安装配置 Nginx 超详细图文教程</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/157569.html" target="_blank" title="Nive 云计算与大数据之间的羁绊(期末不挂科版):云计算 | 大数据 | Hadoop | HDFS | MapReduce | Hive | Spark">Nive 云计算与大数据之间的羁绊(期末不挂科版):云计算 | 大数据 | Hadoop | HDFS | MapReduce | Hive | Spark</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15786067.html" target="_blank" title="架构 云原生 Spring Cloud Gateway 网关整合 Knife4j 4.3 实现微服务接口文档聚合">架构 云原生 Spring Cloud Gateway 网关整合 Knife4j 4.3 实现微服务接口文档聚合</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/17819196.html" target="_blank" title="记一次spring cloud gateway Netty线程性能优化(附带压测)">记一次spring cloud gateway Netty线程性能优化(附带压测)</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/1359189.html" target="_blank" title="java 开发语言 【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka">java 开发语言 【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15779785.html" target="_blank" title="pytorch ffmpeg ai AI编程 【小沐学Python】Python实现语音识别(Whisper)">pytorch ffmpeg ai AI编程 【小沐学Python】Python实现语音识别(Whisper)</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/15780880.html" target="_blank" title="如何3分钟在 Windows 11 上启用 Copilot">如何3分钟在 Windows 11 上启用 Copilot</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li><li class="widget-list-item"><div class="widget-post-list-item"><div class="list-body"> <a class="list-title" href="https://www.51969.com/post/18743299.html" target="_blank" title="超级详细的电脑通过网线连接树莓派操作步骤,以及无法查询到树莓派ip的解决办法(本人亲自踩坑无数总结而来,学不会来揍我系列)">超级详细的电脑通过网线连接树莓派操作步骤,以及无法查询到树莓派ip的解决办法(本人亲自踩坑无数总结而来,学不会来揍我系列)</a> </div><div class="list-footer"> <span>2024-05-07</span> </div></div></li></ul></div><div class="widget ifread www_51969_com" id="side-new-comment-item"><h3 class="function_t">最新评论</h3><ul><li><a href="https://www.51969.com/post/18845667.html#cmt1499" title="heze在MQTTNET mqtt客户端 mqtt发布 mqtt订阅 .net C#MQTT编程06--MQTT服务器和客户端(winform版)的评论"><img alt="heze" src="https://www.51969.com/zb_users/avatar/0.png" class="avatar" height="24" width="24"><p>真好</p><span>2024-05-07</span></a></li><li><a href="https://www.51969.com/post/18732400.html#cmt1492" title="gg在kubernetes 容器 云原生 K8s(七):部署、使用 metrics-server的评论"><img alt="gg" src="https://www.51969.com/zb_users/avatar/0.png" class="avatar" height="24" width="24"><p>湖广会馆湖广会馆湖广会馆湖广会馆韩国货</p><span>2024-05-06</span></a></li><li><a href="https://www.51969.com/post/18722929.html#cmt1485" title="你好在c语言 visual studio github 内容运营 软件工程 一篇文章让你完全掌握使用Git推送代码到新版GitCode的评论"><img alt="你好" src="https://www.51969.com/zb_users/avatar/0.png" class="avatar" height="24" width="24"><p>可以这样子</p><span>2024-05-06</span></a></li><li><a href="https://www.51969.com/post/18771271.html#cmt1478" title="你好在百度 搜索引擎 用户运营 内容运营 流量运营 头条搜索下拉词怎么做?高粱seo实战告诉你答案的评论"><img alt="你好" src="https://www.51969.com/zb_users/avatar/0.png" class="avatar" height="24" width="24"><p>这个效果不错</p><span>2024-05-06</span></a></li><li><a href="https://www.51969.com/post/18808420.html#cmt1471" title="学生在python 后端 django直播带货系统的设计与实现(程序+开题报告)的评论"><img alt="学生" src="https://www.51969.com/zb_users/avatar/0.png" class="avatar" height="24" width="24"><p>想要源码</p><span>2024-05-03</span></a></li><li><a href="https://www.51969.com/post/51969.html#cmt1464" title="归海奕筎在完全免费白嫖chatGPT-4的终极方法!的评论"><img alt="归海奕筎" src="https://www.51969.com/zb_users/avatar/0.png" class="avatar" height="24" width="24"><p>好想白嫖。</p><span>2024-04-30</span></a></li></ul></div></aside> </div><script>var billmE = new Array("","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Spt","Oct","Nov","Dec"); var billhost = "https://www.51969.com/",billtxt1 = "老司机,路子野,随时超车",billtxt2 = "POWERED: Z-BLOGPHP THEMES: YEELZ",billurl = "https://www.51969.com/post/18747240.html",billtag = "前端",billtitle = "react.js javascript 前端 npm 设置你的第一个React应用",billcont = "目录一、React入门1.1 你好React1.2 创建React1.3 应用结构二、总结2.1 定义组件2.2 组件源码三、组...",billimg = "https://www.51969.com/zb_users/plugin/zharry_Reading_time/images/tishi.gif",billlogo = "https://www.51969.com/zb_users/theme/Jz52_tsqa/bill/logo.png",billd = "06",billY = "2024",billm = billmE[parseInt("5")]; var hbtim = '<div class="img_time">'+billd+'<span>'+billm+'. '+billY+'</span></div>';</script><link href="https://www.51969.com/zb_users/theme/Jz52_tsqa/bill/bill.css" media="all" rel="stylesheet"><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/bill/html2canvas.min.js"></script><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/bill/bill.js"></script><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/bill/billgo.js"></script><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/script/asid.js"></script> <div id="footer"> <p><div><a href="https://www.51969.com/" target="_blank">金钥匙</a> | <a href="https://www.51969.com/sitemap/map.xml" target="_blank">网站地图</a> | <a href="http://ai.51969.com/" target="_blank">金钥匙ai</a> | <a href="http://yzkb.51969.com/" target="_blank">柚子快报</a> | <a href="https://www.51969.com/user/51969561/" target="_blank">柚子快报教程</a> | <a href="http://yzkbyqm.51969.com/" target="_blank">柚子快报邀请码</a> | <a href="http://yzkbjhm.51969.com/" target="_blank">柚子快报激活码</a></div><div>本站部分信息来自互联网收集,仅供学习和交流,如有侵权、后门、不妥之处,请联系我们进行删除处理。 </div><script charset="UTF-8" id="kuazhi_ai_click" src="https://kuazhi.com/kuazhi_ai_click.js"></script><div>金钥匙www.51969.com.2009-2024 All Rights Reserved.</div><script charset="UTF-8" id="LA_COLLECT" src="//sdk.51.la/js-sdk-pro.min.js"></script><script>LA.init({id:"JsGTT7LZ90ZlKYPn",ck:"JsGTT7LZ90ZlKYPn"})</script> <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">浙ICP备15009899号-2</a></p></p> </div></div></div><a href="javascript:void(0);" class="to-top" id="to-top"><i class="jzicon-jzzhiding"></i><em>返回顶部</em></a><a class="jznight" href="javascript:switchNightMode()" target="_self"><i class="jzicon-yejian-b"></i><em>暗黑模式</em></a><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/script/custom.js?v1.0.9"></script><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/script/qrcode.min.js"></script><script src="https://www.51969.com/zb_users/plugin/gbll_rollname/names.js"></script><script src="https://www.51969.com/zb_users/plugin/gbll_rollname/roll.js"></script><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/script/sticky-left.js"></script><script src="https://www.51969.com/zb_users/theme/Jz52_tsqa/script/sidebar-right.js"></script><div id="ly_cache" data-id="18747240"></div></body></html><!--ly_cache 2024-05-08 01:26:52-->