reduxjs 实践

reduxjs 类组件中使用

在React类组件中使用Redux,你需要使用connect函数从react-redux库中导入,并将你的组件传递给它。connect函数会处理组件的状态和动作创建器的连接,并返回一个新的已连接组件,你需要将这个组件导入到你的项目中使用。

以下是一个简单的例子:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actionCreators from './actions'; // 假设你有一个actionCreators.js文件
import { getData } from './reducer'; // 假设你有一个reducer.js文件
 
class MyComponent extends Component {
  componentDidMount() {
    this.props.actionCreators.fetchData();
  }
 
  render() {
    return (
      <div>
        {this.props.data}
      </div>
    );
  }
}
 
const mapStateToProps = (state) => ({
  data: getData(state)
});
 
const mapDispatchToProps = (dispatch) => ({
  actionCreators: bindActionCreators(actionCreators, dispatch)
});
 
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(MyComponent);

在这个例子中,MyComponent是一个React类组件,它在组件挂载后会通过调用从actionCreators中绑定的fetchData方法来触发一个action。mapStateToProps函数将state映射到组件的props,而mapDispatchToProps将action创建器绑定到props中。最后,connect函数将这两者连接到MyComponent,并导出已连接的组件供其他部分使用。

reduxjs 处理异步请求

在Redux中处理异步请求通常涉及使用中间件,如redux-thunkredux-saga。以下是使用redux-thunk中间件处理异步操作的一个简单例子。

首先,安装redux-thunk

npm install redux-thunk

然后,配置redux-thunk中间件:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
 
const store = createStore(rootReducer, applyMiddleware(thunk));

接下来,在action creator中返回一个函数,而不是一个对象。该函数接收dispatch作为参数,并可以进行异步操作:

import axios from 'axios';
 
export const fetchData = () => async (dispatch) => {
  try {
    dispatch({ type: 'FETCH_REQUEST' });
    const response = await axios.get('/api/data');
    dispatch({ type: 'FETCH_SUCCESS', payload: response.data });
  } catch (error) {
    dispatch({ type: 'FETCH_FAILURE', error: error.message });
  }
};

在上述代码中,fetchData是一个返回函数的action creator,该函数接收dispatch作为参数,并在API调用期间分发不同的action。

最后,在组件中,你可以这样使用这个action creator:

import React from 'react';
import { useDispatch } from 'react-redux';
import { fetchData } from './actions';
 
export const MyComponent = () => {
  const dispatch = useDispatch();
 
  const handleFetch = () => {
    dispatch(fetchData());
  };
 
  return (
    <button onClick={handleFetch}>Fetch Data</button>
  );
};

当按钮被点击时,fetchData action creator被调度,并执行异步请求。

@reduxjs/toolkit 类组件中使用

在使用 @reduxjs/toolkit 时,可以利用它提供的 configureStore 方法创建一个 Redux store,并使用 createSlice 方法定义切片(slice),然后将切片的 reducer 注册到 store 中。在类组件中,可以通过 connect 方法从 react-redux 库将组件连接到 Redux store。

以下是一个简单的例子:

// store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
 
export default configureStore({
  reducer: {
    counter: counterReducer,
  },
});
 
// counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
 
const initialState = {
  value: 0,
};
 
export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: state => {
      state.value += 1;
    },
    decrement: state => {
      state.value -= 1;
    },
  },
});
 
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
 
// CounterComponent.jsx
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { increment, decrement } from './counterSlice';
 
class CounterComponent extends Component {
  render() {
    const { value, incrementAction, decrementAction } = this.props;
    return (
      <div>
        <p>Counter Value: {value}</p>
        <button onClick={incrementAction}>Increment</button>
        <button onClick={decrementAction}>Decrement</button>
      </div>
    );
  }
}
 
const mapStateToProps = state => ({
  value: state.counter.value,
});
 
const mapDispatchToProps = {
  incrementAction: increment,
  decrementAction: decrement,
};
 
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(CounterComponent);s

在这个例子中,我们创建了一个名为 counter 的切片,并定义了 increment 和 decrement 的 Reducer 函数。然后,我们在 CounterComponent 类组件中使用 connect 方法将 store 中的 state 和 dispatch 的 actions 连接到组件的 props 中,并在组件内使用它们。

@reduxjs/toolkit处理异步请求

在Redux Toolkit中,你可以使用createAsyncThunk来创建可以处理异步请求的Thunk action creators。以下是一个简单的例子,演示如何使用@reduxjs/toolkit来处理异步请求:

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
 
// 异步请求的Thunk action creator
export const fetchUser = createAsyncThunk(
  'user/fetchUser',
  async (userId) => {
    const response = await axios.get(`/api/users/${userId}`);
    return response.data;
  }
);
 
// 创建slice来管理状态
const userSlice = createSlice({
  name: 'user',
  initialState: {
    data: null,
    status: 'idle',
    error: null,
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUser.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(fetchUser.fulfilled, (state, action) => {
        state.status = 'succeeded';
        state.data = action.payload;
      })
      .addCase(fetchUser.rejected, (state, action) => {
        state.status = 'failed';
        state.error = action.error.message;
      });
  },
});
 
export default userSlice.reducer;

在上面的代码中,fetchUser是一个createAsyncThunk创建的异步action。它会根据用户ID从某个API异步请求用户数据。在reducer中,我们通过addCase方法来处理异步action的pending、fulfilled和rejected状态。这样的处理方式使得代码更加清晰和可维护。