从 Redux 迁移到 React Context API + hooks 时如何处理副作用
How to handle side effects when migrating from Redux to React Context API + hooks
如果你有一个 Redux 应用程序,你想迁移到新的 React 上下文 API + hooks (useReducer),你将如何替换 redux-saga 或 redux-thunk 来处理副作用?让我们以 redux-saga 的 github 页面为例:
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
function* mySaga() {
yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}
function* mySaga() {
yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}
export default mySaga;
如果不使用 Redux 而使用 React Context api + hooks 来做同样的事情,推荐的最佳实践是什么?
看看 useEffect
钩子。这就是你用来产生副作用的东西。
https://reactjs.org/docs/hooks-effect.html
以下是如何从您的组件调用 api 并呈现数据的示例:
import ReactDOM from "react-dom";
import React, { useState, useEffect } from "react";
import axios from "axios";
function SearchResults() {
const [data, setData] = useState(null);
useEffect(() => {
function getFetchUrl() {
return "https://hn.algolia.com/api/v1/search?query=react";
}
async function fetchData() {
console.log("asdasd");
const result = await axios(getFetchUrl());
setData(result.data);
}
fetchData();
}, []);
return <div>{JSON.stringify(data)}</div>;
}
ReactDOM.render(<SearchResults />, document.getElementById("root"));
我部分从 overreacted.io 中获取了这段代码,我强烈建议您阅读这篇关于 useEffect
钩子的精彩文章:https://overreacted.io/a-complete-guide-to-useeffect/
关于 useReducer
,它基本上是 useState
类固醇。它允许您处理更复杂的状态操作,但实际上并没有太大区别。
如果您希望状态由不同的组件共享,您可以使用 useContext
但它与副作用的工作方式无关。
----关于redux:
我还想评论一下,如果您只是将数据传递给嵌套组件,那么在您的应用程序中使用 React Context api + hooks 来替换 redux 可能会很好。但是如果你想要所有很棒的工具、中间件、devtools 等,Redux 仍然是一个不错的选择,即使有 hooks,它们也不是相互排斥的。
参见:
https://blog.isquaredsoftware.com/2019/03/presentation-state-of-redux/
具体来说
https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/10
https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/11
如果你有一个 Redux 应用程序,你想迁移到新的 React 上下文 API,你需要能够将数据获取到层次结构中的任何组件,你需要能够将您的视图逻辑与业务逻辑分开,您需要能够拆分业务逻辑,这意味着模块化,这意味着单个文件中没有 1000 个 LOC。
除非别无选择,否则我会坚持使用 Redux。使用 Redux,您可以获得出色的文档,文档写得很好,您通常可以理解发生了什么。设计模式是 well-known,它们的支持和 open-source 专门用于 Redux 的库已经足够了。
使用 Context,您不必使用单独的库,仅此而已。这是使用 Context 代替 Redux 的唯一好处。由于 cross-cutting 构建商店时的顾虑,上下文有其自身的挑战。
如果你有一个 Redux 应用程序,你想迁移到新的 React 上下文 API + hooks (useReducer),你将如何替换 redux-saga 或 redux-thunk 来处理副作用?让我们以 redux-saga 的 github 页面为例:
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
function* mySaga() {
yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}
function* mySaga() {
yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}
export default mySaga;
如果不使用 Redux 而使用 React Context api + hooks 来做同样的事情,推荐的最佳实践是什么?
看看 useEffect
钩子。这就是你用来产生副作用的东西。
https://reactjs.org/docs/hooks-effect.html
以下是如何从您的组件调用 api 并呈现数据的示例:
import ReactDOM from "react-dom";
import React, { useState, useEffect } from "react";
import axios from "axios";
function SearchResults() {
const [data, setData] = useState(null);
useEffect(() => {
function getFetchUrl() {
return "https://hn.algolia.com/api/v1/search?query=react";
}
async function fetchData() {
console.log("asdasd");
const result = await axios(getFetchUrl());
setData(result.data);
}
fetchData();
}, []);
return <div>{JSON.stringify(data)}</div>;
}
ReactDOM.render(<SearchResults />, document.getElementById("root"));
我部分从 overreacted.io 中获取了这段代码,我强烈建议您阅读这篇关于 useEffect
钩子的精彩文章:https://overreacted.io/a-complete-guide-to-useeffect/
关于 useReducer
,它基本上是 useState
类固醇。它允许您处理更复杂的状态操作,但实际上并没有太大区别。
如果您希望状态由不同的组件共享,您可以使用 useContext
但它与副作用的工作方式无关。
----关于redux:
我还想评论一下,如果您只是将数据传递给嵌套组件,那么在您的应用程序中使用 React Context api + hooks 来替换 redux 可能会很好。但是如果你想要所有很棒的工具、中间件、devtools 等,Redux 仍然是一个不错的选择,即使有 hooks,它们也不是相互排斥的。
参见:
https://blog.isquaredsoftware.com/2019/03/presentation-state-of-redux/ 具体来说 https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/10 https://blog.isquaredsoftware.com/presentations/2019-03-state-of-redux/#/11
如果你有一个 Redux 应用程序,你想迁移到新的 React 上下文 API,你需要能够将数据获取到层次结构中的任何组件,你需要能够将您的视图逻辑与业务逻辑分开,您需要能够拆分业务逻辑,这意味着模块化,这意味着单个文件中没有 1000 个 LOC。
除非别无选择,否则我会坚持使用 Redux。使用 Redux,您可以获得出色的文档,文档写得很好,您通常可以理解发生了什么。设计模式是 well-known,它们的支持和 open-source 专门用于 Redux 的库已经足够了。
使用 Context,您不必使用单独的库,仅此而已。这是使用 Context 代替 Redux 的唯一好处。由于 cross-cutting 构建商店时的顾虑,上下文有其自身的挑战。