组件

本文由 AI 协助更新

组件负责渲染。本文介绍组件与元素、Props、State、单向数据流等基本概念。


认识组件和元素

组件是一个特殊的函数,它返回 null 或元素。

function TodoItem() {
  return <Text>买菜</Text>
}

如上,TodoItem 就是一个组件,Text 也是一个组件,用于渲染文本。

什么是元素呢?

<Text>买菜</Text> 就是一个元素。

这种把组件包裹在一对尖括号的语法称为 JSXopen in new window,它是一种语法糖。

const element = <Text>买菜</Text>

上面这行代码最终被 Babel 编译为:

const element = React.createElement(Text, null, '买菜')

可以自己试试看open in new window

createElement 接受三个参数,第一个指定要渲染的组件,第二个指定组件的属性,第三个参数指定子元素

一些注意事项:

  • 组件函数名以大写字母开头

  • 组件返回 null,代表什么也不渲染

认识 Props

在下面这个例子中,TodoItem 组件渲染的文本是被写死的:

function TodoItem() {
  return <Text>买菜</Text>
}

如何动态改变呢?我们通过定义属性(Props)来解决。

interface TodoItemProps {
  title: string
}

function TodoItem(props: TodoItemProps) {
  return <Text>{props.title}</Text>
}

function App() {
  return (
    <View>
      <TodoItem title="买菜" />
      <TodoItem title="写代码" />
      <TodoItem title="运动" />
    </View>
  )
}











 
 
 



titleTodoItem 组件的属性,我们在 App 组件中为 title 属性赋值。

这样,title 就没有写死在 TodoItem 组件中,而是由使用它的组件来决定。

认识 State

上面这个例子还是不够动态,title 属性虽然没有写死在 TodoItem 中,但是却写死在 App 中。有没有更动态的方法呢?

在这里,我们使用状态

import React, { useState } from 'react'
import { View, Text, TextInput, Button, StyleSheet } from 'react-native'

interface TodoItemProps {
  title: string
}

function TodoItem(props: TodoItemProps) {
  return <Text style={styles.todoText}>{props.title}</Text>
}

function App() {
  const [currentTodo, setCurrentTodo] = useState('')
  const [inputText, setInputText] = useState('')
  
  return (
    <View style={styles.container}>
      <TodoItem title={currentTodo || '请输入待办事项'} />
      <TextInput 
        value={inputText} 
        onChangeText={setInputText} 
        placeholder="输入待办事项"
        style={styles.input} 
      />
      <Button title="添加" onPress={() => setCurrentTodo(inputText)} />
    </View>
  )
}
 












 



 










我们从 react 导入 useStateopen in new window,用 const [currentTodo, setCurrentTodo] = useState('') 得到当前值和更新函数;setCurrentTodo 被调用后组件会重新渲染,新的 currentTodo 会传给 TodoItem 的 title。像这样由 useState 创建的变量称为状态 (State)。变量名可自定,setter 引用稳定,可安全传给子组件或放入依赖数组。

State vs Props

状态是由组件内部自己维护的,是可变的。

属性是由组件外部传递进来的,是不可变的。

❗ 如果属性是一个对象,注意不要改变这个对象的属性,不可变只是规则,是需要我们自觉维护的。

状态或属性发生变化,将导致 UI 发生变化,我们通过改变数据来改变 UI。数据变了,UI 也就变了。

数据驱动视图。

单向数据流

useState 创建 inputText / setInputText,把 inputText 赋给 TextInput 的 value,把 setInputText 赋给 onChangeText:显示什么、输入时做什么都由父组件 App 决定,这就是受控组件。数据从父流向子,不能反向,即单向数据流

若在 onChangeText 里对输入做处理再 setInputText,例如过滤数字:

<TextInput
  value={inputText}
  onChangeText={(value) => setInputText(value.replace(/[0-9]/g, ''))}
  placeholder="输入待办事项"
  style={styles.input}
/>


 



在上面的代码中,我们把用户输入中的所有数字都过滤掉,再作为参数传递给 setInputText

setInputText 被调用后,inputText 就会发生变化,而 inputText 刚好被赋值给了 TextInput 的属性 value,然后用户看到的输入就是没有数字的文本。

自定义组件应尽量受控。点击「添加」时用 onPress={() => setCurrentTodo(inputText)} 把输入同步到状态,界面随之更新。


目录

  1. 组件 — 认识组件和元素、Props、State、单向数据流
  2. useState、useReducer、useContext
  3. useEffect、useEffectEvent
  4. 闭包陷阱、useRef
  5. useCallback、useMemo、React.memo
  6. Hook 规则、自定义 Hook
上次更新: