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;


评论(共0条)