初识redux

Redux 是一个用于管理 JavaScript 应用程序状态的可预测状态容器

核心概念

1. 单一数据源

整个应用的状态被存储在一个单一的对象树(store)中,这个对象树位于唯一的 store 里。

创建store:

const store = createStore(reducer)
2. 状态是只读的

唯一改变状态的方法是触发一个 action,action 是一个描述状态变化的纯对象。这保证了所有的状态变化都是可追踪的。

一个标准的 action 对象至少包含一个 type 属性,用于描述要执行的操作类型,除此之外,还可以携带额外的数据(通常命名为 payload),用于传递与该操作相关的具体信息。其基本结构如下:

{
  type: 'ACTION_TYPE',
  // 可选的额外数据
  payload: {
    // 这里可以包含任意数量和类型的数据
    key1: value1,
    key2: value2
  }
}
3. 使用纯函数来执行修改

为了描述 action 如何改变状态树,需要编写 reducers。reducer 是一个纯函数,reducer 接收两个参数,当前的状态(state)和一个 action 对象(action),并返回一个新的状态。

// 定义初始状态
const initialState = {
    todos: []
};

// 定义 reducer
const todoReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'ADD_TODO':
            return {
                ...state,
                todos: [...state.todos, action.payload]
            };
        case 'DELETE_TODO':
            return {
                ...state,
                todos: state.todos.filter(todo => todo.id!== action.payload)
            };
        default:
            return state;
    }
};

// 测试 reducer
const addTodoAction = {
    type: 'ADD_TODO',
    payload: { id: 1, text: '学习 Redux' }
};
const newState = todoReducer(initialState, addTodoAction);
console.log(newState); 

获取reducer中返回的state数据:

 store.getState()

 用于发送action,来修改reducer中的state数据:

 store.dispatch()

 用来注册监听state是否改变:

 store.subscribe()

工作流程 

  1. 发起 Action:组件触发一个 action,这个 action 描述了想要发生的状态变化。
  2. Reducer 处理:store 接收到 action 后,将当前状态和 action 传递给 reducer。
  3. 状态更新:reducer 根据 action 的类型返回一个新的状态,store 更新其内部的状态树。
  4. 组件更新:组件订阅 store 的变化,当状态更新时,组件会重新渲染。
// 引入 redux
const { createStore } = require('redux');

// 定义 reducer
const counterReducer = (state = { counter: 0 }, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return {
        ...state,
        counter: state.counter + 1
      };
    case 'DECREMENT':
      return {
        ...state,
        counter: state.counter - 1
      };
    default:
      return state;
  }
};

// 创建 store
const store = createStore(counterReducer);

// 订阅状态变化
store.subscribe(() => {
  console.log('当前状态:', store.getState());
});

// 发起 action
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' });

 

Redux 中间件

Redux 中间件可以在 action 被 dispatch 到 reducer 之前对其进行拦截和处理,常见的中间件有 redux-thunk 和 redux-promise 等,用于处理异步操作。例如使用 redux-thunk 处理异步请求:

const { createStore, applyMiddleware } = require('redux');
const thunk = require('redux-thunk').default;

// 异步 action 创建函数
const fetchData = () => {
  return (dispatch) => {
    dispatch({ type: 'FETCH_DATA_REQUEST' });
    setTimeout(() => {
      dispatch({ type: 'FETCH_DATA_SUCCESS', payload: 'Data fetched successfully' });
    }, 1000);
  };
};

// 定义 reducer
const dataReducer = (state = { loading: false, data: null }, action) => {
  switch (action.type) {
    case 'FETCH_DATA_REQUEST':
      return {
        ...state,
        loading: true
      };
    case 'FETCH_DATA_SUCCESS':
      return {
        ...state,
        loading: false,
        data: action.payload
      };
    default:
      return state;
  }
};

// 创建 store 并应用中间件
const store = createStore(dataReducer, applyMiddleware(thunk));

// 发起异步 action
store.dispatch(fetchData());

 

Redux 与 React 集成

通常使用 react-redux 库将 Redux 与 React 集成,它提供了 Provider 组件和 connect 函数(或 useSelector 和 useDispatch Hooks)来连接 React 组件和 Redux store。示例如下:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';

// 定义 reducer
const counterReducer = (state = { counter: 0 }, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return {
        ...state,
        counter: state.counter + 1
      };
    case 'DECREMENT':
      return {
        ...state,
        counter: state.counter - 1
      };
    default:
      return state;
  }
};

// 创建 store
const store = createStore(counterReducer);

// 定义 React 组件
const Counter = () => {
  const counter = useSelector((state) => state.counter);
  const dispatch = useDispatch();

  return (
    

计数器: {counter}

); }; // 渲染应用 const root = ReactDOM.createRoot(document.getElementById('root')); root.render( );

你可能感兴趣的:(前端知识,react,js,typescript)