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的工作原理,并向您介绍服务器和客户端组件之间的区别。

相关推荐
阿伟来咯~12 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端17 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱20 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai29 分钟前
uniapp
前端·javascript·vue.js·uni-app
bysking1 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云2 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:137971205872 小时前
web端手机录音
前端