zy-smile

通过AI对话的方式学习React——(下)

Redux

var code = "f3b9363b-ccf1-4b9f-ada6-038af338147b"

现在前端框架虽然语法和api不一样,但是其实大部分实现原理都是一样的,都是基于原生js开发的,我现在用的主要技术栈是Vue2,Vue3这些,想着去react的官方文档去一步一步的学习有些麻烦,而且英文文档看着也很吃力,于是想着能不能借助AI工具根据vue的知识体系去学习react的语法,这样无非就是根据现有的vue知识体系换一种实现语法,可以达到触类旁通的目的,这样学起来省时多了。

AI工具可以用Chatgpt或者其他Ai工具,市面上的AI工具还是挺多的,包括百度的文心一言、讯飞的火星大模型,下面是我借助抖音的AI工具豆包来学习的。

下面是react状态管理的学习记录,react框架和路由的学习跳转

[通过Ai对话的方式来学习React]

通过AI对话的方式学习React—(中)

react的状态管理库有哪些

在 React 里,有不少状态管理库可供选择,下面为你介绍一些常见的库及其特点:

1. Redux

  • 特点:遵循单向数据流架构,通过 action 触发状态改变,借助 reducer 纯函数处理状态更新。它具有可预测性、方便调试、利于代码复用等优点,适用于大型复杂应用。
  • 适用场景:当应用规模较大、状态逻辑复杂、需要时间旅行调试或者多人协作开发时,Redux 是不错的选择。

2. MobX

  • 特点:采用响应式编程思想,自动追踪状态的依赖关系,当状态发生变化时,自动更新依赖该状态的组件。它的代码简洁,开发效率高。
  • 适用场景:适用于对开发效率要求较高、状态变化逻辑相对简单的项目。

3. Recoil

  • 特点:由 Facebook 开发,提供了一种简单且灵活的状态管理方式。它使用原子(atom)来表示状态,组件可以订阅这些原子,当原子状态发生变化时,订阅的组件会自动更新。
  • 适用场景:适合需要在不同组件之间共享状态,且希望状态管理逻辑简单易懂的项目。

4. Zustand

  • 特点:轻量级状态管理库,使用简单,没有复杂的概念和模板代码。它基于 Hooks 实现,易于集成到 React 项目中。
  • 适用场景:对于小型项目或者希望快速实现状态管理的场景非常合适。

5. Context API(React 自带)

  • 特点:是 React 内置的状态管理方案,用于在组件树中共享数据,避免了层层传递 props 的问题。但它更适合简单的状态共享,不适合复杂的状态管理。
  • 适用场景:当需要在多个组件之间共享一些简单的状态,如主题、用户信息等时,可以使用 Context API。

redux怎么实现数据管理的

Redux 是一种用于管理 React 应用程序状态的可预测状态容器,它遵循单向数据流架构,实现数据管理主要基于以下几个核心概念和步骤:

核心概念

  1. Action(动作):是一个描述状态变化的对象,它包含一个 type 属性,用于描述动作的类型,还可以包含其他可选的属性来传递数据。
  2. Reducer(纯函数):接收当前状态和一个动作作为参数,返回一个新的状态。Reducer 必须是纯函数,即相同的输入总是产生相同的输出,且不产生任何副作用。
  3. Store(存储):是应用程序的状态容器,它持有整个应用的状态,并提供了一些方法来管理状态,如 dispatch 方法用于分发动作,subscribe 方法用于注册监听器。
  4. View(视图):即 React 组件,通过订阅 Store 中的状态变化来更新 UI。

实现步骤

1. 定义 Action

Action 是一个简单的 JavaScript 对象,包含一个 type 属性和可选的 payload 属性。

// actions.js
// 定义一个 action type
const ADD_TODO = 'ADD_TODO';

// 定义一个 action creator
export const addTodo = (text) => ({
    type: ADD_TODO,
    payload: text
});

2. 定义 Reducer

Reducer 是一个纯函数,根据不同的 action type 来更新状态。

// reducers.js
const initialState = {
    todos: []
};

const todoReducer = (state = initialState, action) => {
    switch (action.type) {
        case 'ADD_TODO':
            return {
                ...state,
                todos: [...state.todos, action.payload]
            };
        default:
            return state;
    }
};

export default todoReducer;

3. 创建 Store

使用 createStore 函数创建一个 Store,并将 Reducer 传递给它。

// store.js
import { createStore } from 'redux';
import todoReducer from './reducers';

const store = createStore(todoReducer);

export default store;

4. 在 React 组件中使用 Store

使用 react-redux 库将 Redux Store 与 React 组件连接起来。

// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={store}>
        <App />
    </Provider>
);
// App.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addTodo } from './actions';

const App = () => {
    const todos = useSelector((state) => state.todos);
    const dispatch = useDispatch();

    const handleAddTodo = (text) => {
        dispatch(addTodo(text));
    };

    return (
        <div>
            <input
                type="text"
                placeholder="Add a todo"
                onKeyPress={(e) => {
                    if (e.key === 'Enter') {
                        handleAddTodo(e.target.value);
                        e.target.value = '';
                    }
                }}
            />
            <ul>
                {todos.map((todo, index) => (
                    <li key={index}>{todo}</li>
                ))}
            </ul>
        </div>
    );
};

export default App;

工作流程总结

  1. 用户交互:用户在视图(React 组件)中进行操作,触发一个 Action。
  2. 分发 Action:通过 dispatch 方法将 Action 发送到 Store。
  3. Reducer 处理:Store 接收到 Action 后,将当前状态和 Action 传递给 Reducer。
  4. 状态更新:Reducer 根据 Action 的类型返回一个新的状态,Store 更新其内部状态。
  5. 视图更新:React 组件通过 useSelector 订阅 Store 中的状态变化,当状态更新时,组件重新渲染,更新 UI。

redux怎么实现异步数据更新

在 Redux 里,Reducer 必须是纯函数,不能包含异步操作,所以要实现异步数据更新,需要借助中间件。下面介绍几种常用中间件实现异步数据更新的方法。

1. 使用 Redux-Thunk

Redux-Thunk 是一款常用的中间件,它能让 action creator 返回一个函数而非对象,从而在这个函数里执行异步操作。

安装

npm install redux-thunk

代码示例

2. 使用 Redux-Saga

Redux-Saga 利用生成器函数来管理异步操作,它把异步逻辑从 action creatorreducer 中分离出来,让代码结构更清晰。

安装

npm install redux-saga

代码示例

 //app.js
    import React from 'react';
     import { useDispatch, useSelector } from 'react-redux';
     import { fetchData } from './actions';

	const App = () => {
    const dispatch = useDispatch();
    const { data, loading, error } = useSelector((state) => state);

    const handleFetchData = () => {
        dispatch(fetchData());
    };

	    return (
	        <div>
	            <button onClick={handleFetchData}>Fetch Data</button>
	            {loading && <p>Loading...</p>}
	            {error && <p>Error: {error}</p>}
	            {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
	        </div>
	    );
	};

	export default App;  
  
	//actiion.js
    import { createAsyncThunk } from '@reduxjs/toolkit';
	import axios from 'axios';

	// 定义异步 Action
	export const fetchData = () => {
    return async (dispatch) => {
        dispatch({ type: 'FETCH_DATA_REQUEST' });
        try {
            const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
            dispatch({ type: 'FETCH_DATA_SUCCESS', payload: response.data });
        } catch (error) {
            dispatch({ type: 'FETCH_DATA_FAILURE', payload: error.message });
        }
    };
	};    
//reducers.js
	const initialState = {
    data: null,
    loading: false,
    error: null
	};

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

	export default dataReducer; 

 //store.js
    import { createStore, applyMiddleware } from 'redux';
	import thunk from 'redux-thunk';
	import dataReducer from './reducers';

	const store = createStore(dataReducer, applyMiddleware(thunk));

	export default store;  

总结

  • Redux-Thunk:简单易用,适合小型项目或者对异步操作要求不复杂的场景。
  • Redux-Saga:代码结构更清晰,适合处理复杂的异步逻辑,如异步流程控制、监听多个 action 等。

redux怎么实现类似vue的getter函数

在 Vue 里,`getter` 函数能让我们以计算属性的形式获取 store 中的数据,并且可以对这些数据进行加工处理。在 Redux 中,虽然没有原生的 `getter` 概念,但可以借助 `reselect` 库实现类似的功能。`reselect` 库能创建可记忆的(memoized)、可组合的选择器函数,下面详细介绍实现步骤。

安装 reselect

npm install reselect

代码示例


	// App.js
	import React from 'react';
	import { useSelector } from 'react-redux';
	import { selectCompletedTodos, selectIncompletedTodos } from './selectors';

	const App = () => {
    const completedTodos = useSelector(selectCompletedTodos);
    const incompletedTodos = useSelector(selectIncompletedTodos);

    return (
        <div>
            <h2>已完成的任务</h2>
            <ul>
                {completedTodos.map((todo) => (
                    <li key={todo.id}>{todo.text}</li>
                ))}
            </ul>
            <h2>未完成的任务</h2>
            <ul>
                {incompletedTodos.map((todo) => (
                    <li key={todo.id}>{todo.text}</li>
                ))}
            </ul>
        </div>
    );
	};
	export default App;  
// index.js
	import React from 'react';
	import ReactDOM from 'react-dom/client';
	import { Provider } from 'react-redux';
	import store from './store';
	import App from './App';
	
	const root = ReactDOM.createRoot(document.getElementById('root'));
	root.render(
    <Provider store={store}>
        <App />
    </Provider>
	);      
    
 // reducers.js
	const initialState = {
    todos: [
        { id: 1, text: '学习 Redux', completed: false },
        { id: 2, text: '掌握 reselect', completed: true },
        { id: 3, text: '实践项目', completed: false }
    ]
	};

	const todoReducer = (state = initialState, action) => {
    switch (action.type) {
        // 这里可以添加更多 action 处理逻辑
        default:
            return state;
    }
	};

	export default todoReducer;    
    
    

	// selectors.js
	import { createSelector } from 'reselect';

	// 基础选择器,获取 todos 列表
	const selectTodos = (state) => state.todos;

	// 定义类似 getter 的选择器函数,获取已完成的 todos
	export const selectCompletedTodos = createSelector(
    [selectTodos],
    (todos) => todos.filter((todo) => todo.completed)
    );

	// 定义类似 getter 的选择器函数,获取未完成的 todos
	export const selectIncompletedTodos = createSelector(
    [selectTodos],
    (todos) => todos.filter((todo) => !todo.completed)
	);    

	// store.js
	import { createStore } from 'redux';
	import todoReducer from './reducers';
	
	const store = createStore(todoReducer);
	
	export default store;   

代码解释

  1. 基础选择器:在 selectors.js 里,selectTodos 是基础选择器,它接收整个 Redux 状态作为参数,返回 todos 列表。
  2. 组合选择器:借助 createSelector 函数创建组合选择器,像 selectCompletedTodosselectIncompletedTodos。这些选择器以基础选择器为输入,并且有记忆功能。也就是说,只有当输入的基础选择器结果发生变化时,组合选择器才会重新计算,否则会返回之前缓存的结果。
  3. 在组件中使用:在 App.js 组件里,通过 useSelector 钩子调用这些选择器函数,进而获取经过处理的数据。

通过这种方式,你可以在 Redux 里实现类似 Vue 的 getter 功能,对 store 中的数据进行计算和加工。

posted on 2025-04-29 11:47  指尖de跃动  阅读(1)  评论(0)    收藏  举报  来源

导航