React Native核心概念 #

概述 #

React Native 基于 React,因此继承了 React 的核心概念。理解这些概念对于开发高质量的 React Native 应用至关重要。

组件 #

组件是 React Native 应用的基本构建块。每个组件描述了界面的一部分。

函数组件 #

推荐使用函数组件:

tsx
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';

interface GreetingProps {
  name: string;
}

const Greeting: React.FC<GreetingProps> = ({name}) => {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Hello, {name}!</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 10,
  },
  text: {
    fontSize: 18,
    color: '#333',
  },
});

export default Greeting;

类组件 #

虽然不推荐,但类组件仍然可用:

tsx
import React, {Component} from 'react';
import {View, Text} from 'react-native';

interface Props {
  name: string;
}

interface State {
  count: number;
}

class Counter extends Component<Props, State> {
  state = {
    count: 0,
  };

  increment = () => {
    this.setState({count: this.state.count + 1});
  };

  render() {
    return (
      <View>
        <Text>Hello, {this.props.name}!</Text>
        <Text>Count: {this.state.count}</Text>
      </View>
    );
  }
}

Props(属性) #

Props 是从父组件传递给子组件的数据,是只读的。

基本用法 #

tsx
interface CardProps {
  title: string;
  description?: string;
  onPress?: () => void;
}

const Card: React.FC<CardProps> = ({title, description, onPress}) => {
  return (
    <TouchableOpacity onPress={onPress}>
      <View style={styles.card}>
        <Text style={styles.title}>{title}</Text>
        {description && (
          <Text style={styles.description}>{description}</Text>
        )}
      </View>
    </TouchableOpacity>
  );
};

// 使用
<Card 
  title="React Native" 
  description="跨平台移动开发框架"
  onPress={() => console.log('Card pressed')}
/>

默认 Props #

tsx
interface ButtonProps {
  title: string;
  color?: string;
  size?: 'small' | 'medium' | 'large';
}

const Button: React.FC<ButtonProps> = ({
  title,
  color = '#007AFF',
  size = 'medium',
}) => {
  const sizeStyles = {
    small: {paddingVertical: 8, paddingHorizontal: 16},
    medium: {paddingVertical: 12, paddingHorizontal: 24},
    large: {paddingVertical: 16, paddingHorizontal: 32},
  };

  return (
    <TouchableOpacity style={[styles.button, {backgroundColor: color}, sizeStyles[size]]}>
      <Text style={styles.text}>{title}</Text>
    </TouchableOpacity>
  );
};

Props 传递模式 #

展开传递 #

tsx
const Parent = () => {
  const config = {
    title: 'My Card',
    description: 'Description',
    onPress: () => {},
  };

  return <Card {...config} />;
};

子组件传递 #

tsx
interface ContainerProps {
  children: React.ReactNode;
  style?: object;
}

const Container: React.FC<ContainerProps> = ({children, style}) => {
  return <View style={[styles.container, style]}>{children}</View>;
};

// 使用
<Container style={{backgroundColor: '#f5f5f5'}}>
  <Text>Content here</Text>
</Container>

State(状态) #

State 是组件内部管理的可变数据。当 state 改变时,组件会重新渲染。

useState Hook #

tsx
import React, {useState} from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';

const Counter = () => {
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  const increment = () => {
    setCount(count + step);
  };

  const decrement = () => {
    setCount(count - step);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.count}>{count}</Text>
      <View style={styles.buttons}>
        <TouchableOpacity style={styles.button} onPress={decrement}>
          <Text style={styles.buttonText}>-</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.button} onPress={increment}>
          <Text style={styles.buttonText}>+</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

函数式更新 #

当新状态依赖于旧状态时,使用函数式更新:

tsx
const [count, setCount] = useState(0);

// 不推荐
setCount(count + 1);

// 推荐
setCount(prev => prev + 1);

对象状态 #

tsx
interface User {
  name: string;
  age: number;
  email: string;
}

const [user, setUser] = useState<User>({
  name: '',
  age: 0,
  email: '',
});

// 更新部分属性
const updateName = (name: string) => {
  setUser(prev => ({...prev, name}));
};

数组状态 #

tsx
const [items, setItems] = useState<string[]>([]);

// 添加元素
const addItem = (item: string) => {
  setItems(prev => [...prev, item]);
};

// 删除元素
const removeItem = (index: number) => {
  setItems(prev => prev.filter((_, i) => i !== index));
};

// 更新元素
const updateItem = (index: number, newValue: string) => {
  setItems(prev => prev.map((item, i) => (i === index ? newValue : item)));
};

生命周期 #

函数组件使用 Hooks 来处理生命周期相关的逻辑。

useEffect #

useEffect 用于处理副作用:

tsx
import React, {useState, useEffect} from 'react';

const UserProfile: React.FC<{userId: string}> = ({userId}) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  // 组件挂载时执行
  useEffect(() => {
    fetchUser(userId);
  }, [userId]);

  // 清理函数
  useEffect(() => {
    const subscription = subscribeToUpdates();

    return () => {
      subscription.unsubscribe();
    };
  }, []);

  const fetchUser = async (id: string) => {
    setLoading(true);
    const data = await fetch(`/api/users/${id}`);
    setUser(data);
    setLoading(false);
  };

  if (loading) {
    return <LoadingSpinner />;
  }

  return (
    <View>
      <Text>{user?.name}</Text>
    </View>
  );
};

useEffect 依赖数组 #

tsx
// 每次渲染后执行
useEffect(() => {
  console.log('组件渲染');
});

// 仅挂载时执行
useEffect(() => {
  console.log('组件挂载');
}, []);

// 依赖变化时执行
useEffect(() => {
  console.log('userId 变化:', userId);
}, [userId]);

useLayoutEffect #

在 DOM 更新后同步执行,适合需要同步读取布局的场景:

tsx
import React, {useLayoutEffect, useRef} from 'react';
import {View, Text, findNodeHandle, measure} from 'react-native';

const Tooltip: React.FC = () => {
  const ref = useRef<View>(null);
  const [position, setPosition] = useState({x: 0, y: 0});

  useLayoutEffect(() => {
    if (ref.current) {
      ref.current.measure((x, y, width, height, pageX, pageY) => {
        setPosition({x: pageX, y: pageY});
      });
    }
  }, []);

  return <View ref={ref}>{/* ... */}</View>;
};

条件渲染 #

if 语句 #

tsx
const Greeting: React.FC<{isLoggedIn: boolean}> = ({isLoggedIn}) => {
  if (isLoggedIn) {
    return <Text>Welcome back!</Text>;
  }
  return <Text>Please log in</Text>;
};

三元运算符 #

tsx
const Status: React.FC<{isLoading: boolean}> = ({isLoading}) => {
  return (
    <View>
      {isLoading ? <ActivityIndicator /> : <Text>Content loaded</Text>}
    </View>
  );
};

逻辑与运算符 #

tsx
const Notification: React.FC<{count: number}> = ({count}) => {
  return (
    <View>
      {count > 0 && <Text>{count} unread messages</Text>}
    </View>
  );
};

列表渲染 #

使用 map #

tsx
const TodoList: React.FC<{items: string[]}> = ({items}) => {
  return (
    <View>
      {items.map((item, index) => (
        <Text key={index}>{item}</Text>
      ))}
    </View>
  );
};

使用 FlatList(推荐) #

tsx
import {FlatList} from 'react-native';

interface Item {
  id: string;
  title: string;
}

const TodoList: React.FC<{items: Item[]}> = ({items}) => {
  const renderItem = ({item}: {item: Item}) => (
    <View style={styles.item}>
      <Text>{item.title}</Text>
    </View>
  );

  return (
    <FlatList
      data={items}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      ItemSeparatorComponent={() => <View style={styles.separator} />}
      ListEmptyComponent={<Text>No items</Text>}
    />
  );
};

使用 SectionList #

tsx
import {SectionList} from 'react-native';

interface Section {
  title: string;
  data: Item[];
}

const GroupedList: React.FC<{sections: Section[]}> = ({sections}) => {
  return (
    <SectionList
      sections={sections}
      renderItem={({item}) => <Text>{item.title}</Text>}
      renderSectionHeader={({section}) => (
        <Text style={styles.header}>{section.title}</Text>
      )}
      keyExtractor={item => item.id}
    />
  );
};

组件通信 #

父传子(Props) #

tsx
const Parent = () => {
  const [value, setValue] = useState('');

  return <Child value={value} onChange={setValue} />;
};

const Child = ({value, onChange}) => (
  <TextInput value={value} onChangeText={onChange} />
);

子传父(回调函数) #

tsx
const Parent = () => {
  const handleChildEvent = (data) => {
    console.log('Received from child:', data);
  };

  return <Child onEvent={handleChildEvent} />;
};

const Child = ({onEvent}) => (
  <Button onPress={() => onEvent({message: 'Hello'})} title="Send" />
);

兄弟组件通信(状态提升) #

tsx
const Parent = () => {
  const [sharedValue, setSharedValue] = useState('');

  return (
    <View>
      <SiblingA value={sharedValue} />
      <SiblingB onChange={setSharedValue} />
    </View>
  );
};

性能优化 #

React.memo #

防止不必要的重新渲染:

tsx
const ExpensiveComponent = React.memo<Props>(({data}) => {
  return <View>{/* 复杂渲染逻辑 */}</View>;
});

// 自定义比较函数
const MemoizedComponent = React.memo(
  ({item}) => <Item item={item} />,
  (prevProps, nextProps) => prevProps.item.id === nextProps.item.id
);

useMemo #

缓存计算结果:

tsx
const ExpensiveList: React.FC<{items: Item[]}> = ({items}) => {
  const sortedItems = useMemo(() => {
    return items.sort((a, b) => a.name.localeCompare(b.name));
  }, [items]);

  return <FlatList data={sortedItems} renderItem={renderItem} />;
};

useCallback #

缓存回调函数:

tsx
const Parent = () => {
  const [count, setCount] = useState(0);
  const [items, setItems] = useState([]);

  const handlePress = useCallback(() => {
    console.log('Button pressed');
  }, []);

  const handleItemPress = useCallback((id: string) => {
    console.log('Item pressed:', id);
  }, []);

  return (
    <View>
      <ChildButton onPress={handlePress} />
      <ItemList items={items} onItemPress={handleItemPress} />
    </View>
  );
};

总结 #

React Native 的核心概念与 React 一致,包括:

  • 组件:构建界面的基本单元
  • Props:父组件传递给子组件的只读数据
  • State:组件内部的可变数据
  • 生命周期:组件的创建、更新和销毁过程
  • Hooks:函数组件的状态管理方式

理解这些概念是开发 React Native 应用的基础。

接下来,让我们学习 React Native 的基础组件。

继续学习 基础组件,掌握 View、Text、Image 等核心组件的使用。

最后更新:2026-03-28