# React进阶
# 状态管理
# Redux
import { createStore } from 'redux'
function counter(state = { count: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 }
case 'DECREMENT':
return { count: state.count - 1 }
default:
return state
}
}
const store = createStore(counter)
store.dispatch({ type: 'INCREMENT' })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# React-Redux
import { connect } from 'react-redux'
const mapStateToProps = state => ({
count: state.count
})
const mapDispatchToProps = dispatch => ({
increment: () => dispatch({ type: 'INCREMENT' })
})
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 路由
# React Router
import { BrowserRouter, Route, Link } from 'react-router-dom'
function App() {
return (
<BrowserRouter>
<div>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</div>
</BrowserRouter>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 性能优化
# React.memo
const MyComponent = React.memo(function MyComponent({ name }) {
return <div>{name}</div>
})
1
2
3
2
3
# useMemo
const expensiveValue = useMemo(() => {
return computeExpensiveValue(a, b)
}, [a, b])
1
2
3
2
3
# useCallback
const memoizedCallback = useCallback(
() => {
doSomething(a, b)
},
[a, b]
)
1
2
3
4
5
6
2
3
4
5
6
# 代码分割
const OtherComponent = React.lazy(() => import('./OtherComponent'))
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
)
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 高级模式
# 高阶组件(HOC)
function withSubscription(WrappedComponent, selectData) {
return class extends React.Component {
constructor(props) {
super(props)
this.state = {
data: selectData(DataSource, props)
}
}
componentDidMount() {
DataSource.addChangeListener(this.handleChange)
}
componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange)
}
handleChange = () => {
this.setState({
data: selectData(DataSource, this.props)
})
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Render Props
class Mouse extends React.Component {
constructor(props) {
super(props)
this.state = { x: 0, y: 0 }
}
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{this.props.render(this.state)}
</div>
)
}
}
function App() {
return (
<Mouse render={({ x, y }) => (
<h1>The mouse position is ({x}, {y})</h1>
)} />
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 错误边界
class ErrorBoundary extends React.Component {
constructor(props) {
super(props)
this.state = { hasError: false }
}
static getDerivedStateFromError(error) {
return { hasError: true }
}
componentDidCatch(error, errorInfo) {
console.log(error, errorInfo)
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>
}
return this.props.children
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 最佳实践
- 组件拆分: 保持组件小而专注
- Props类型检查: 使用PropTypes或TypeScript
- 避免直接修改state: 使用setState或useState
- key的使用: 列表渲染时使用唯一key
- 避免在render中创建函数: 使用useCallback
- 合理使用useMemo: 避免过度优化
- 代码分割: 使用React.lazy和Suspense
- 错误处理: 使用错误边界捕获组件错误
← React Hooks React实战项目 →