在React学习之旅中,我们已经掌握了许多基础知识。现在来实战一下,创建Alert组件,以此来巩固和运用之前文章中所学的知识。
创建Alert组件
首先,需要在 components
目录中新建 Alert.tsx
文件。在这个文件中,我们将定义Alert组件:
javascript
// Alert.tsx
export default function Alert() {
return (
<div>
<div>
<span role="img" aria-label="Warning">⚠️</span>
<span>警告!</span>
</div>
<div>辰火流光的React学习之路 ...</div>
</div>
);
}
该组件包含一个图标、一个标题和一段文字。我们使用 export default
来导出组件,以便在其他文件中使用它。
需要注意的是,React组件的名称必须以大写字母开头。如果组件名称以小写字母开头,React会将其视为DOM元素,而不是自定义的React组件。
另外,我们也可以使用箭头函数语法来定义React组件。以下是使用箭头函数语法定义的Alert组件:
javascript
// Alert.tsx
const Alert = () => {
return (
<div>
<div>
<span role="img" aria-label="Warning">⚠️</span>
<span>警告!</span>
</div>
<div>辰火流光的React学习之路 ...</div>
</div>
);
};
export default Alert;
在React函数组件中,箭头函数和普通函数并没有显著的差异。你可以根据自己的喜好来选择使用哪种函数语法。我个人更倾向于使用普通函数语法,因为它需要输入的字符较少。
在App组件中添加Alert
创建了Alert组件之后,下一步就是将它添加到主应用中。我们将在 App.tsx
文件中引入并使用Alert组件。
javascript
// App.tsx
import Alert from "./components/Alert.tsx";
function App() {
return (
<>
<Alert/>
</>
)
}
export default App
首先,需要在 App.tsx
文件的顶部引入Alert组件。我们可以使用ES6的模块导入语法(import
)来实现这一点:
然后,可以在App组件的返回值中使用 <Alert/>
标签来使用Alert组件。这里,我们使用了React的Fragment(<>...</>
)语法,它可以让我们返回多个元素,而不需要添加额外的父元素。
现在,当我们在浏览器中打开应用时,就可以看到Alert组件的内容了。
使用props定制Alert组件
可以使用props(属性)来传递数据,从而定制组件的行为和显示。接下来,将在Alert组件中使用props,让它能够显示不同类型的警告信息。
首先,我们需要定义一个接口(AlertProps
)来描述我们的props。这个接口包含三个属性:type
、heading
和children
。type
属性表示警告的类型,可以是info
或warning
;heading
属性表示警告的标题;children
属性表示警告的内容。
然后,我们可以在Alert组件中使用这些props:
tsx
// Alert.tsx
import { ReactNode } from "react";
interface AlertProps {
type: 'info' | 'warning',
heading: string,
children: ReactNode
}
export default function Alert(props: AlertProps) {
return (
<div>
<div>
<span
role="img"
aria-label={
props.type === "warning"
? "Warning"
: "Information"
}
>
{props.type === "warning" ? "⚠️" : "ℹ️"}
</span>
<span>{props.heading}</span>
</div>
<div>{props.children}</div>
</div>
);
}
在使用Alert组件时,我们可以通过属性来传递数据:
tsx
// App.tsx
import Alert from "./components/Alert.tsx";
function App() {
return (
<>
<Alert type="info" heading="成功">
辰火流光的React学习之路!
</Alert>
</>
)
}
export default App
在浏览器中的效果
使用ES6的解构赋值语法来简化我们的代码。解构赋值可以让我们直接从对象中提取属性,而不需要通过对象名来访问这些属性:
javascript
export default function Alert({type,heading,children}: AlertProps) {
// ...
}
为props提供默认值。例如,我们可以将type属性的默认值设置为info:
typescript
// Alert.tsx
interface AlertProps {
type?: 'info' | 'warning', // 1. 在type后增加问号,表示这个属性是可选的
// ...
}
// 2. 在解构的type中增加默认值
export default function Alert({type='info',heading,children}: AlertProps) {
// ...
}
之后调用Alert组件时可以去掉type属性
javascript
// App.tsx
import Alert from "./components/Alert.tsx";
function App() {
return (
<>
<Alert heading="成功"> <- 这里去掉了type属性
辰火流光的React学习之路!
</Alert>
</>
)
}
export default App
浏览器中的效果
使用State
在React中,使用state(状态)来保存和管理组件的内部数据。接下来,我们将在我们的Alert组件中使用state,让它能够根据状态的变化动态地更新显示。
示例代码
javascript
// ...
export default function Alert({type='info',heading,children}: AlertProps) {
const [visible, setVisible] = useState(true); // 1.创建useState
// 2. 若visible为false则返回null
if(!visible){
return null;
}
// ...
}
首先,需要使用useState函数来创建一个状态变量(visible
)和一个更新函数(setVisible
)。visible
变量用来表示Alert组件是否可见,setVisible
函数用来更新visible
的值:
tsx
const [visible, setVisible] = useState(true);
然后,我们可以在组件的渲染函数中使用visible
变量。如果visible
为false
,那么我们就返回null
,这样Alert组件就不会被渲染出来:
tsx
if(!visible){ return null; }
增加关闭按钮
我们将在Alert组件中添加一个关闭按钮。首先,在AlertProps
接口中添加一个closable
属性,用来表示是否显示关闭按钮:
typescript
// Alert.tsx
interface AlertProps {
type?: 'info' | 'warning',
heading: string,
children: ReactNode,
closable: boolean // 1. 增加关闭按钮类型声明
}
// 2. 解构出closable
export default function Alert({type = 'info', heading, children, closable}: AlertProps) {
// ...
}
然后,在组件的渲染函数中使用closable
属性。如果closable
为true
,那么我们就渲染出关闭按钮:
xml
// Alert.tsx
// ...
export default function Alert({type = 'info', heading, children, closable}: AlertProps) {
// ...
<!-- 这里使用closable是否显示关闭按钮 -->
{closable && (
<button aria-label="Close">
<span role="img" aria-label="Close">❌</span>
</button>
)}
}
在使用Alert组件时,我们可以通过closable属性来控制是否显示关闭按钮,其中closable最终会被渲染成closable={true},所以两者写法一致:
javascript
import Alert from "./components/Alert.tsx";
function App() {
return (
<>
<Alert heading="成功" closable>
辰火流光的React学习之路!
</Alert>
</>
)
}
export default App
在浏览器中的效果
增加关闭按钮点击事件
接下来,我们将在我们的Alert组件中添加一个关闭按钮的点击事件,让用户可以通过点击关闭按钮来隐藏Alert组件。
首先,我们需要在Alert组件中定义一个事件处理函数(handleCloseClick
)。这个函数会在用户点击关闭按钮时被调用,它的作用是将visible
状态变量的值设置为false
。
然后,我们可以在关闭按钮的元素上添加一个onClick属性,将它的值设置为handleCloseClick函数。这样,当用户点击关闭按钮时,handleCloseClick函数就会被调用:
javascript
// ...
export default function Alert({type = 'info', heading, children, closable}: AlertProps) {
const [visible, setVisible] = useState(true);
// 1.声明点击事件,改为visible的值
function handleCloseClick(){
setVisible(false)
}
return (
// ...
{closable && (
<button aria-label="Close" onClick={handleCloseClick}> <- 2。
然后,我们可以在关闭按钮的元素上添加一个onClick属性,将它的值设置为handleCloseClick函数。这样,当用户点击关闭按钮时,handleCloseClick函数就会被调用:调用点击事件
<span role="img" aria-label="Close">❌</span>
</button>
)}
// ...
);
}
在浏览器中的效果
实现关闭按钮点击事件的回调
我们将在Alert组件中添加一个onClose
属性,让用户可以在Alert组件被关闭时执行自定义的操作。
首先,我们需要在AlertProps
接口中添加一个onClose
属性,它的类型是一个没有参数也没有返回值的函数:
然后,我们可以在handleCloseClick
函数中调用onClose
函数。我们需要先检查onClose
是否存在,如果存在,那么我们就调用它:
javascript
// Alert.tsx文件
interface AlertProps {
// ...
// 1.增加函数类型字段
onClose: () => void
}
// 2.props中增加onClose解构
export default function Alert({type = 'info', heading, children, closable, onClose}: AlertProps) {
// ...
function handleCloseClick() {
setVisible(false)
// 3.如果onClose存在就调用它
if(onClose){
onClose()
}
}
// ...
}
在使用Alert组件时,我们可以通过onClose
属性来传递一个函数,这个函数会在Alert组件被关闭时被调用:
javascript
// App.tsx文件
import Alert from "./components/Alert.tsx";
function App() {
return (
<>
<Alert
heading="成功"
closable={true}
onClose={() => { <- 这里增加onClose属性,传递一个函数,在控制台打印信息
console.log('我被关闭了')
}}
>
辰火流光的React学习之路!
</Alert>
</>
)
}
export default App
在浏览器中的效果