文章目录
组件化是现代前端开发的核心思想之一,它使得开发者能够将复杂的应用分解成一系列可复用的小型模块。React和React Native都采用了这一思想,并将其发挥到了极致。
React组件化基础
组件的概念
- 组件是React中的基本构建块。
- 组件可以接收props(属性)和state(状态)。
- 组件可以嵌套其他组件。
创建组件
函数式组件:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
类组件:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
状态管理
使用useState
或useReducer
管理状态:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
生命周期
函数式组件使用useEffect:
import { useEffect } from 'react';
function Example() {
useEffect(() => {
// 在组件挂载时执行
console.log('Component mounted');
return () => {
// 在组件卸载时执行
console.log('Component unmounted');
};
}, []);
return <div>Hello</div>;
}
类组件使用生命周期方法:
class Example extends React.Component {
componentDidMount() {
console.log('Component mounted');
}
componentWillUnmount() {
console.log('Component unmounted');
}
render() {
return <div>Hello</div>;
}
}
传递props
父组件向子组件传递数据:
function Parent() {
return <Child name="Alice" />;
}
function Child(props) {
return <h1>Hello, {props.name}</h1>;
}
事件处理
处理用户交互:
function Greeting() {
const [name, setName] = useState('');
return (
<div>
<input value={name} onChange={(e) => setName(e.target.value)} />
<h1>Hello, {name}</h1>
</div>
);
}
React Native组件化基础
React Native概述
- React Native是一个用于构建原生移动应用的框架。
- 它使用React的组件化思想,并提供了丰富的原生组件。
创建组件
函数式组件:
import React from 'react';
import { Text, View } from 'react-native';
function Welcome({ name }) {
return <Text>Hello, {name}</Text>;
}
类组件:
import React, { Component } from 'react';
import { Text, View } from 'react-native';
class Welcome extends Component {
render() {
return <Text>Hello, {this.props.name}</Text>;
}
}
状态管理
使用useState或useReducer管理状态:
import React, { useState } from 'react';
import { Text, View, Button } from 'react-native';
function Counter() {
const [count, setCount] = useState(0);
return (
<View>
<Text>You clicked {count} times</Text>
<Button title="Click me" onPress={() => setCount(count + 1)} />
</View>
);
}
生命周期
函数式组件使用useEffect:
import React, { useEffect } from 'react';
import { Text, View } from 'react-native';
function Example() {
useEffect(() => {
console.log('Component mounted');
return () => {
console.log('Component unmounted');
};
}, []);
return <Text>Hello</Text>;
}
类组件使用生命周期方法:
import React, { Component } from 'react';
import { Text, View } from 'react-native';
class Example extends Component {
componentDidMount() {
console.log('Component mounted');
}
componentWillUnmount() {
console.log('Component unmounted');
}
render() {
return <Text>Hello</Text>;
}
}
传递props
父组件向子组件传递数据:
import React from 'react';
import { Text, View } from 'react-native';
function Parent() {
return <Child name="Alice" />;
}
function Child({ name }) {
return <Text>Hello, {name}</Text>;
}
事件处理
处理用户交互:
import React, { useState } from 'react';
import { Text, TextInput, View } from 'react-native';
function Greeting() {
const [name, setName] = useState('');
return (
<View>
<TextInput value={name} onChangeText={(text) => setName(text)} />
<Text>Hello, {name}</Text>
</View>
);
}
组件化的高级技巧
高阶组件(Higher-Order Components, HOCs)
HOCs是一种模式,用于增强现有组件的功能。
示例:日志记录HOC:
function withLogging(WrappedComponent) {
return function EnhancedComponent(props) {
console.log('Rendering component');
return <WrappedComponent {...props} />;
};
}
const LoggedWelcome = withLogging(Welcome);
Context API
Context API用于在组件树中传递数据。
示例:主题上下文:
import React, { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<div>
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
<Child />
</div>
</ThemeContext.Provider>
);
}
function Child() {
const { theme } = useContext(ThemeContext);
return <div style={{ backgroundColor: theme === 'light' ? 'white' : 'black' }}>Child</div>;
}
Redux
Redux是一个用于状态管理的库。
示例:使用Redux管理全局状态:
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const initialState = { count: 0 };
function reducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
default:
return state;
}
}
const store = createStore(reducer);
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const unsubscribe = store.subscribe(() => {
const newState = store.getState();
setCount(newState.count);
});
return () => {
unsubscribe();
};
}, []);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => store.dispatch({ type: 'INCREMENT' })}>
Click me
</button>
</div>
);
}
实战案例:构建一个简单的计数器应用
React版本
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(count - 1)}>Decrement</button>
</div>
);
}
export default Counter;
React Native版本
import React, { useState } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
function Counter() {
const [count, setCount] = useState(0);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>You clicked {count} times</Text>
<TouchableOpacity onPress={() => setCount(count + 1)}>
<Text>Increment</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setCount(count - 1)}>
<Text>Decrement</Text>
</TouchableOpacity>
</View>
);
}
export default Counter;
组件优化与性能提升
性能优化的重要性
- 组件的性能直接影响到用户体验。
- 通过优化组件,可以显著提高应用的性能。
React.memo 和 React.PureComponent
- React.memo 是一个高阶组件,用于避免不必要的渲染。
- React.PureComponent 是一个类组件基类,自动实现浅比较。
示例:使用 React.memo
import React, { memo } from 'react';
const Item = memo(({ item }) => {
return <div>{item}</div>;
});
function List({ items }) {
return (
<div>
{items.map((item) => (
<Item key={item.id} item={item} />
))}
</div>
);
}
export default List;
示例:使用 React.PureComponent
import React, { PureComponent } from 'react';
class Item extends PureComponent {
render() {
return <div>{this.props.item}</div>;
}
}
function List({ items }) {
return (
<div>
{items.map((item) => (
<Item key={item.id} item={item} />
))}
</div>
);
}
export default List;
shouldComponentUpdate 和 useLayoutEffect
- shouldComponentUpdate 方法允许自定义更新逻辑。
- useLayoutEffect 用于在DOM更新之前执行副作用。
示例:使用 shouldComponentUpdate
import React, { Component } from 'react';
class Item extends Component {
shouldComponentUpdate(nextProps) {
return nextProps.item !== this.props.item;
}
render() {
return <div>{this.props.item}</div>;
}
}
function List({ items }) {
return (
<div>
{items.map((item) => (
<Item key={item.id} item={item} />
))}
</div>
);
}
export default List;
示例:使用 useLayoutEffect
import React, { useLayoutEffect } from 'react';
function Item({ item }) {
useLayoutEffect(() => {
console.log('Item rendered:', item);
}, [item]);
return <div>{item}</div>;
}
function List({ items }) {
return (
<div>
{items.map((item) => (
<Item key={item.id} item={item} />
))}
</div>
);
}
export default List;
组件通信与状态管理
组件间通信
- 父子组件间的通信。
- 兄弟组件间的通信。
父子组件通信
function Parent() {
const [name, setName] = useState('Alice');
const handleNameChange = (newName) => {
setName(newName);
};
return (
<div>
<Child onNameChange={handleNameChange} />
<h1>Hello, {name}</h1>
</div>
);
}
function Child({ onNameChange }) {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value);
};
const handleSubmit = () => {
onNameChange(inputValue);
};
return (
<div>
<input type="text" value={inputValue} onChange={handleChange} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
export default Parent;
兄弟组件通信
import React, { useState } from 'react';
function App() {
const [name, setName] = useState('Alice');
return (
<div>
<ChildA name={name} />
<ChildB setName={setName} />
</div>
);
}
function ChildA({ name }) {
return <h1>Hello, {name}</h1>;
}
function ChildB({ setName }) {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value);
};
const handleSubmit = () => {
setName(inputValue);
};
return (
<div>
<input type="text" value={inputValue} onChange={handleChange} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
export default App;
状态管理库
- Redux
- MobX
- Context API
示例:使用 Redux
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const initialState = { count: 0 };
function reducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
default:
return state;
}
}
const store = createStore(reducer);
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
const unsubscribe = store.subscribe(() => {
const newState = store.getState();
setCount(newState.count);
});
return () => {
unsubscribe();
};
}, []);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => store.dispatch({ type: 'INCREMENT' })}>
Increment
</button>
<button onClick={() => store.dispatch({ type: 'DECREMENT' })}>
Decrement
</button>
</div>
);
}
export default () => (
<Provider store={store}>
<App />
</Provider>
);
示例:使用 MobX
import { observable, autorun } from 'mobx';
import { observer } from 'mobx-react-lite';
const store = observable({
count: 0,
increment() {
this.count++;
},
decrement() {
this.count--;
}
});
const App = observer(() => (
<div>
<p>You clicked {store.count} times</p>
<button onClick={store.increment}>Increment</button>
<button onClick={store.decrement}>Decrement</button>
</div>
));
export default App;
React与React Native的异同
React vs React Native
- API相似性:两者都使用JSX语法和组件化思想。
- 平台差异:React用于Web开发,React Native用于移动应用开发。
- DOM vs Native Components:React使用虚拟DOM,React Native使用原生组件。
跨平台开发
- React Native支持iOS和Android平台。
- 可以编写共享代码并在不同平台上运行。
示例:跨平台计数器
import React, { useState } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
function Counter() {
const [count, setCount] = useState(0);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>You clicked {count} times</Text>
<TouchableOpacity onPress={() => setCount(count + 1)}>
<Text>Increment</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setCount(count - 1)}>
<Text>Decrement</Text>
</TouchableOpacity>
</View>
);
}
export default Counter;