通过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框架和路由的学习跳转
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 应用程序状态的可预测状态容器,它遵循单向数据流架构,实现数据管理主要基于以下几个核心概念和步骤:
核心概念
- Action(动作):是一个描述状态变化的对象,它包含一个
type属性,用于描述动作的类型,还可以包含其他可选的属性来传递数据。 - Reducer(纯函数):接收当前状态和一个动作作为参数,返回一个新的状态。Reducer 必须是纯函数,即相同的输入总是产生相同的输出,且不产生任何副作用。
- Store(存储):是应用程序的状态容器,它持有整个应用的状态,并提供了一些方法来管理状态,如
dispatch方法用于分发动作,subscribe方法用于注册监听器。 - 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;
工作流程总结
- 用户交互:用户在视图(React 组件)中进行操作,触发一个 Action。
- 分发 Action:通过
dispatch方法将 Action 发送到 Store。 - Reducer 处理:Store 接收到 Action 后,将当前状态和 Action 传递给 Reducer。
- 状态更新:Reducer 根据 Action 的类型返回一个新的状态,Store 更新其内部状态。
- 视图更新:React 组件通过
useSelector订阅 Store 中的状态变化,当状态更新时,组件重新渲染,更新 UI。
redux怎么实现异步数据更新
在 Redux 里,Reducer 必须是纯函数,不能包含异步操作,所以要实现异步数据更新,需要借助中间件。下面介绍几种常用中间件实现异步数据更新的方法。
1. 使用 Redux-Thunk
Redux-Thunk 是一款常用的中间件,它能让 action creator 返回一个函数而非对象,从而在这个函数里执行异步操作。
安装
npm install redux-thunk
代码示例
2. 使用 Redux-Saga
Redux-Saga 利用生成器函数来管理异步操作,它把异步逻辑从 action creator 和 reducer 中分离出来,让代码结构更清晰。
安装
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;
代码解释
- 基础选择器:在
selectors.js里,selectTodos是基础选择器,它接收整个 Redux 状态作为参数,返回todos列表。 - 组合选择器:借助
createSelector函数创建组合选择器,像selectCompletedTodos和selectIncompletedTodos。这些选择器以基础选择器为输入,并且有记忆功能。也就是说,只有当输入的基础选择器结果发生变化时,组合选择器才会重新计算,否则会返回之前缓存的结果。 - 在组件中使用:在
App.js组件里,通过useSelector钩子调用这些选择器函数,进而获取经过处理的数据。
通过这种方式,你可以在 Redux 里实现类似 Vue 的 getter 功能,对 store 中的数据进行计算和加工。
浙公网安备 33010602011771号