Next.js14从入门到实战004:React基础篇之React进阶

使用Props显示数据

到前一课为止,如果你要复用你的 <Header /> 组件,里面的内容不可改变。

JSX 复制代码
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
      <Header />
    </div>
  );
}

但是,如果你想传递不同的文本,或者外部源获取数据变更,而无法更新信息,该怎么办?

常规 HTML 元素具有可用于传递更改这些元素行为信息的属性。

例如,更改 <img> 元素的 src 属性会更改显示的图像。更改 <a> 标签的 href 属性会更改链接的目标。

同样,你可以将值作为属性传递给 React 组件。

这些称为 props ,例如,我们平常操作的按钮的可能状态有三种:

与 JavaScript 函数类似,你可以设计接受自定义参数的组件,这些参数会更改组件的行为或显示的内容。然后,你可以将这些参数从父组件传递到子组件。

注意:在 React 中,数据沿着组件树向动。这称为单向数据流。而我们后面讲的状态State,则可以作为参数从父组件传递到子组件。

如何使用Props?

HomePage 组件中,你可以将自定义 title prop 传递给 Header 组件,就像传递 HTML 属性一样:

JSX 复制代码
function HomePage() {
  return (
    <div>
      <Header title="React" />
    </div>
  );
}

并且 Header ,子组件可以接受这些 props 作为其第一个函数参数:

JSX 复制代码
function Header(props) {
  return <h1>你好</h1>;
}

如果你 console.log() 支持,你可以看到它是一个带有 title 属性的对象。

JSX 复制代码
function Header(props) {
  console.log(props); // { title: "React" }
  return <h1>你好</h1>;
}

由于 props 是一个对象,因此可以使用对象解构来显式命名函数参数中的 props 值:

JSX 复制代码
function Header({ title }) {
  console.log(title); // "React"
  return <h1>你好</h1>;
}

然后,你可以将 <h1> 标记的内容替换为你的 title 变量。

JSX 复制代码
function Header({ title }) {
  console.log(title);
  return <h1>title</h1>;
}

如果你在浏览器中打开文件,你将看到它正在显示实际的单词"title"。这是因为 React 认为你打算将纯文本字符串渲染给 DOM。

你需要一种方法来告诉 React 这是一个 JavaScript 变量。

在 JSX 中使用变量

要使用 title 道具,请添加大括号 {} 。这些是一种特殊的 JSX 语法,允许你直接在 JSX 标记中编写常规 JavaScript。

JSX 复制代码
function Header({ title }) {
  console.log(title);
  return <h1>{title}</h1>;
}

你可以将大括号视为当你处于"JSX 领域"时进入"JavaScript 领域"的一种方式。你可以在大括号内添加任何 JavaScript 表达式(计算结果为单个值的内容)。例如:

  1. 带有点表示法的对象属性:
JSX 复制代码
function Header(props) {
  return <h1>{props.title}</h1>;
}
  1. 模板字符串:
JSX 复制代码
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
  1. 函数的返回值:
JSX 复制代码
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}
 
function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
  1. 三元运算符
JSX 复制代码
function Header({ title }) {
  return <h1>{title ? title : 'Default Title'}</h1>;
}

你现在可以将任何字符串传给你的 title prop,而且如果你使用三元运算符,你甚至可以快速进行数据判断,并给出默认值:

JSX 复制代码
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

你的组件现在可以使用通用属性 prop,您可以在应用程序的不同部分复用该 prop。您需要做的就是更改属性字符串:

JSX 复制代码
function HomePage() {
  return (
    <div>
      <Header title="React" />
      <Header title="A new title" />
    </div>
  );
}

遍历列表

通常需要将数据显示为列表。您可以使用数组方法来操作数据并生成样式相同但包含不同信息的 UI 元素。

将以下名称数组添加到组件 HomePage

JSX 复制代码
function HomePage() {
  const names = ['张三', '李四', '王五'];
 
  return (
    <div>
      <Header title="你好" />
    </div>
  );
}

然后,可以使用该 array.map() 方法循环访问数组,并使用箭头函数将名称映射到列表项:

JSX 复制代码
function HomePage() {
  const names = ['张三', '李四', '王五'];
 
  return (
    <div>
      <Header title="你好" />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

请注意,你可以使用大括号在"JavaScript"和"JSX"区域之间进行代码切换。也就是说要在JSX里面使用JavaScript,你得写在{}里面。

现在,如果你运行这段代码,React 会给我们一个关于缺少 key prop 的警告。这是因为 React 需要一些东西来唯一标识数组中的项,以便它知道要在 DOM 中更新哪些元素。

你现在可以直接把key的值设置为name的值,因为它们当前是唯一的,但建议使用保证唯一的名称,例如项目 ID。

JSX 复制代码
function HomePage() {
  const names = ['张三', '李四', '王五'];
 
  return (
    <div>
      <Header title="你好" />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
    </div>
  );
}

深入了解React数据传递

使用State添加状态与交互

我们现在来探讨一下 React 如何帮助我们增加状态和事件处理程序的交互性。

例如,让我们在 HomePage 组件中创建一个"赞"按钮。首先,在 return() 语句中添加一个 button 元素:

JSX 复制代码
function HomePage() {
  const names = ['张三', '李四', '王五'];
  return (
    <div>
      <Header title="你好" />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
      <button>Like</button>
    </div>
  );
}

事件监听

若要使按钮在单击时执行某些操作,可以使用以下 onClick 事件:

javascript 复制代码
function HomePage() {
  // ...
  return (
    <div>
      {/* ... */}
      <button onClick={}>Like</button>
    </div>
  );
}

在 React 中,事件名称是小驼峰格式。该 onClick 事件是可用于响应用户交互的众多事件之一。例如,您可以在Input中使用 onChange或在Form中使用 onSubmit

事件绑定

您可以定义一个函数,以便在触发事件时"绑定"事件。在返回语句之前创建一个函数,名为 handleClick()

JSX 复制代码
function HomePage() {
  // ...
 
  function handleClick() {
    console.log("点赞啦~")
  }
 
  return (
    <div>
      {/* ... */}
	  <button onClick={}>Like</button>
    </div>
     )
   }

然后,您可以在触发 onClick 事件时调用该 handleClick 函数:

JSX 复制代码
function HomePage() {
  // 	...
  function handleClick() {
    console.log('点赞啦~');
  }
 
  return (
    <div>
      {/* ... */}
      <button onClick={handleClick}>Like</button>
    </div>
  );
}

你现在可以看下运行效果。

状态State和钩子Hooks

React 有一组称为钩子的函数。钩子允许您向组件添加其他逻辑,例如状态。可以将状态视为 UI 中随时间变化的任何信息,通常由用户交互触发。

您可以使用状态来存储和增加用户单击"赞"按钮的次数。事实上,用于管理状态的 React 钩子被称为: useState()

添加到 useState() 您的项目。它返回一个数组,您可以使用数组解构在组件中访问和使用这些数组值:

JSX 复制代码
function HomePage() {
  // ...
  const [] = React.useState();
 
  // ...
}

数组中的第一项是 状态 value ,您可以命名任何内容。建议将其命名为描述性名称:

JSX 复制代码
function HomePage() {
  // ...
  const [likes] = React.useState();
 
  // ...
}

数组中的第二项是值 update 的函数。您可以将更新函数命名为任何名称,但通常要为其前缀, set 后跟要更新的状态变量的名称:

JSX 复制代码
function HomePage() {
  // ...
  const [likes, setLikes] = React.useState();
 
  // ...
}

您还可以借此机会将状态 likes 的初始值添加到 0

JSX 复制代码
function HomePage() {
  // ...
  const [likes, setLikes] = React.useState(0);
}

然后,您可以使用组件中的状态变量检查初始状态是否正常工作。

javascript 复制代码
function HomePage() {
  // ...
  const [likes, setLikes] = React.useState(0);
  // ...
 
  return (
    // ...
    <button onClick={handleClick}>Like({likes})</button>
  );
}

最后,你可以调用你的状态更新器函数, setLikes 在你的 HomePage 组件中,让我们把它添加到你之前定义的 handleClick() 函数中:

JSX 复制代码
function HomePage() {
  // ...
  const [likes, setLikes] = React.useState(0);
 
  function handleClick() {
    setLikes(likes + 1);
  }
 
  return (
    <div>
      {/* ... */}
      <button onClick={handleClick}>Likes ({likes})</button>
    </div>
  );
}

单击该按钮后,会调用该 handleClick 函数,该函数使用当前点赞数 + 1 的参数,去调用状态更新函数 setLikes

注意:与作为第一个函数参数传递给组件的 prop 不同,状态是在组件中启动并存储的。您可以将状态信息作为 prop 传递给子组件,但更新状态的逻辑应保留在最初创建状态的组件中。

状态管理

这只是对状态的介绍,你可以了解更多关于在 React 应用程序中管理状态和数据流的知识。要了解更多信息,我们建议您阅读 React 文档中的Adding InteractivityManaging State部分。

更多状态资源,可以参考

示例代码

到目前为止,我们探讨了如何开始使用 React。下面的代码是最终代码,请将此代码粘贴到代码编辑器中的 index.html 文件中。

JSX 复制代码
<html>
  <body>
    <div id="app"></div>
 
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
 
    <script type="text/jsx">
      const app = document.getElementById("app")
 
      function Header({ title }) {
        return <h1>{title ? title : "Default title"}</h1>
      }
 
      function HomePage() {
        const names = ['张三', '李四', '王五'];
 
        const [likes, setLikes] = React.useState(0)
 
        function handleClick() {
          setLikes(likes + 1)
        }
 
        return (
          <div>
            <Header title="你好" />
            <ul>
              {names.map((name) => (
                <li key={name}>{name}</li>
              ))}
            </ul>
 
            <button onClick={handleClick}>Like ({likes})</button>
          </div>
        )
      }
 
      const root = ReactDOM.createRoot(app);
      root.render(<HomePage />);
    </script>
  </body>
</html>

通过003和004,你学习了三个基本的 React 概念:组件、属性props和状态state。在这些方面打下坚实的基础将帮助你开始构建 React 应用程序。

在学习 React 时,最好的学习方式是构建。你可以通过使用 <script> 和你到目前为止所学到的知识来逐步采用 React,将小组件添加到现有网站。

从React到Next.js

虽然 React 擅长构建 UI,但将该 UI 独立构建为功能齐全的可扩展应用程序确实需要一些工作。还有一些较新的 React 功能,如服务器和客户端组件,需要一个框架。

而Next.js 处理了大部分设置和配置,并具有帮助您构建 React 应用程序的附加功能。

接下来,我们将把示例从 React 迁移到 Next.js,讨论Next.js的工作原理,并向您介绍服务器和客户端组件之间的区别。

相关推荐
玩电脑的辣条哥2 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ew452182 小时前
ElementUI表格表头自定义添加checkbox,点击选中样式不生效
前端·javascript·elementui
suibian52352 小时前
AI时代:前端开发的职业发展路径拓宽
前端·人工智能
Moon.92 小时前
el-table的hasChildren不生效?子级没数据还显示箭头号?树形数据无法展开和收缩
前端·vue.js·html
垚垚 Securify 前沿站3 小时前
深入了解 AppScan 工具的使用:筑牢 Web 应用安全防线
运维·前端·网络·安全·web安全·系统安全
工业甲酰苯胺5 小时前
Vue3 基础概念与环境搭建
前端·javascript·vue.js
mosquito_lover17 小时前
怎么把pyqt界面做的像web一样漂亮
前端·python·pyqt
柴柴的小记9 小时前
前端vue引入特殊字体不生效
前端·javascript·vue.js
柠檬豆腐脑9 小时前
从前端到全栈:新闻管理系统及多个应用端展示
前端·全栈
bin915310 小时前
DeepSeek 助力 Vue 开发:打造丝滑的颜色选择器(Color Picker)
前端·javascript·vue.js·ecmascript·deepseek