react-redux主要体现分为3部分
action,reducer,store
action
action可以理解成一个动作,通常情况下他是一个对象例如:{type:"ACTION",...},如果使用thunk中间件异步action时,他是一个函数形式;
//action.ts
export const incCount = (info:string) => {
return {
type: "INCREASE",
info
}
}
export const textInp = (info:string) => {
return {
type:"INPTEXT",
info
}
}
reducer
reducer可以理解成为处理action这个动作的一个函数,通常情况下这个函数会传两个参initState、action,项目中可以有多个reducer(下面的代码中,两个reducer我放到一个文件中了),多个reducer可用combineReducers合并使用,如代码所示:
//reducer.ts
import { combineReducers } from "redux"
type IInitState = {
count: number
}
type IInitText = {
text: string
}
type IAction = {
type: string,
info: string
}
const countInitState: IInitState = {
count: 0
}
const textInitState: IInitText = {
text: ""
}
const countReducer = (state = countInitState, action: IAction) => {
switch (action.type) {
case "INCREASE": {
console.log(action.info);
return {
count: state.count + 1
}
}
}
return state
}
const textReducer = (state = textInitState, action: IAction) => {
switch (action.type) {
case "INPTEXT": {
console.log(action.info)
return {
text: state.text + action.info
}
}
}
return state
}
const allReducer = combineReducers({
countReducer,
textReducer
})
export default allReducer
store
store可以理解为项目所有状态的一个仓库,存放所有的reducer,如下代码所示:
//store.ts
import { legacy_createStore as createStore } from "redux";
import allReducer from "./reducer";
const store = createStore(allReducer)
export default store
使用store之前需要使用Provide包裹住整个组件,代码如下:
//App.tsx
const App = () => {
return (
<Provider store={store}>
<ScrollView>
<Home />
<Others />
</ScrollView>
</Provider>
)
}
项目中的使用
react的函数组件和类组件使用redux中的状态的方式是不同的,类组件主要是通过connect(mapStateToProps,mapDispatchToProps)(组件名)形式将状态映射到该组件中,并通过dispatc(action.type)进行状态修改,代码如下所示:
//others.tsx
import React, { PureComponent } from 'react'
import { Button, Text, View } from 'react-native'
import { connect } from 'react-redux'
import { incCount } from '../../store/action'
interface IProps {
count: number,
increase: () => {}
}
class Others extends PureComponent<IProps> {
constructor(props: IProps) {
super(props)
this.state = {
count: 0
}
this.onHandle = this.onHandle.bind(this)
}
onHandle() {
this.props.increase()
}
render() {
let { count } = this.props;
return (
<View>
<Text>
{count}
</Text>
<Button
onPress={this.onHandle}
title="Learn More"
color="#841584"
/>
</View>
)
}
}
const mapStateToProps = (state: any) => {
let { count } = state.countReducer
return {
count
}
}
const mapDispatchToProps = (dispatch: any) => {
return {
increase: () => dispatch(incCount("增加"))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Others)
函数组件主要通过useSelector,useDispatch这两个hook来使用并更改state,代码如下所示:
//Home.tsx
import React, { useEffect, useState } from 'react';
import { SafeAreaView, View, Text, Button, InputAccessoryView, TextInput, ScrollView } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { incCount, textInp } from '../../store/action';
const Home = () => {
const { count } = useSelector((state: any) => state.countReducer)
const { text } = useSelector((state: any) => state.textReducer)
const dispatch = useDispatch()
const onPressInc = () => {
dispatch(incCount("增加"))
}
const onChangeText = (text: string) => {
dispatch(textInp(text))
}
return (
<SafeAreaView>
<View>
<Text>
{count}
{text}
</Text>
<Button
onPress={onPressInc}
title="Learn More"
color="#841584"
/>
<TextInput
style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
onFocus={() => onChangeText(text)}
/>
</View>
</SafeAreaView>
)
}
export default Home
通过以上操作就可以使用store里面的数据了!