6. 使用redux
创建时间:2024-10-30 01:29
长度:3474
浏览:0
评论:0
在Expo 使用redux
安装依赖
yarn add @reduxjs/toolkit react-redux
yarn add redux-devtools-expo-dev-plugin
创建store目录
创建index.ts
import { createSlice, combineSlices, configureStore } from "@reduxjs/toolkit";
import devToolsEnhancer from "redux-devtools-expo-dev-plugin";
import theme from './theme';
export const counterSlice = createSlice({
name: "test",
initialState: {
count: 1111,
},
reducers: {
up: (state) => {
state.count += 1;
},
down: (state) => {
state.count -= 1;
},
},
});
const reducer = combineSlices(counterSlice, theme);
export const store = configureStore({
reducer,
devTools: false,
enhancers: (getDefaultEnhancers) =>
getDefaultEnhancers().concat(devToolsEnhancer()),
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
store/theme.ts
import { createSlice } from "@reduxjs/toolkit";
export const theme = createSlice({
name: "theme",
initialState: {
bottomNav: '#f00'
},
reducers: {
setTabTheme: (state, actions) => {
state.bottomNav = actions.payload;
},
},
});
export const {
setTabTheme
} = theme.actions;
export default theme;
在/app/_layout.tsx修改
#....
import { Provider } from "react-redux";
import { store } from '@/store'
export default function RootLayout() {
return (
<Provider store={store}>
...
</Provider>
);
}
使用
pages/home.tsx
import { View, Text, Button } from "react-native";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch, RootState, counterSlice } from "@/store";
import { setTabTheme } from '@/store/theme'
export default function Home() {
const count = useSelector((state: RootState) => state.test.count);
const bottomNav = useSelector((state: RootState) => state.theme.bottomNav);
const dispatch = useDispatch<AppDispatch>();
return <View>
<Text>hello page home</Text>
<Text>count {count}</Text>
<Button
title="Up"
onPress={() => {
dispatch(counterSlice.actions.up());
}}
/>
<Button
title="Down"
onPress={() => {
dispatch(counterSlice.actions.down());
}}
/>
<Button title="修改主题"
onPress={() => {
dispatch(setTabTheme('green'))
}}
/>
<Text style={{ color: bottomNav}}> colors</Text>
</View>
}
异步请求
注意:这里很多个版本,我当前用的 "@reduxjs/toolkit": "^2.3.0",
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
export const hottest = createSlice({
name: "hottest",
initialState: {
dataSource: [],
loading1: false,
posts: [],
status: 'idle',
error: ''
},
reducers: {
updateLoading(state, action) {
state.loading1 = action.payload;
},
saveDataSource(state, action) {
state.dataSource = action.payload;
}
},
// 在这里处理异步请求的逻辑
extraReducers: builder => {
builder
.addCase(getHottestData.pending, (state, action) => {
state.status = 'loading';
})
.addCase(getHottestData.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message ?? 'Unknown Error'
}).addCase(getHottestData.fulfilled, (state, action) => {
state.status = 'succeeded';
})
}
});
// async request
export const getHottestData: any = createAsyncThunk(
'hottest/hottest',
async(text, thunk) => {
console.log('request start...', text)
let url = `https://api.github.com/search/repositories?q=${text}`;
let res = await fetch(url);
return res.json();
}
)
export const {
updateLoading,
saveDataSource,
} = hottest.actions;
export default hottest;