Rel*_*ros 17 reactjs redux react-hooks
因此,React 16.8中提供了挂钩。从他们的文档来看,Hooks可以作为功能组件中状态的替代者。基本挂钩是:useState
,useEffect
,useContext
,但也有一些额外的钩子,其和为之一useReducer
,它看起来像它使用相同的action-dispatch
的终极版做架构。
问题是,是否由于相似而取代Redux?
是否更适合特定项目?
它适合哪里?
Shu*_*tri 19
Redux是一个以特定方式鼓励数据流的库。
react-redux
另一方面,它实现了React友好的方法,并提供了许多中间件和包装器,因此库使用者不必自己设置整个过程。
虽然useReducer
这是Redux工作方式的一部分,但它并不完全是Redux。为了使您能够使用分派并深入了解组件,您仍然必须结合使用useContext
,useReducer
就像重新发明轮子一样。
除此之外,还useReducer
为您提供了一种dispatch
方法,您可以使用该方法将简单的旧对象作为操作进行分派。目前还没有办法添加middlewares
到这些,例如thunk
,saga
等等。
您也可以在应用程序中使用多个reducer,useReducer
但是将它们组合成一个单一商店的方法仍然必须由开发人员管理。
此外,React docs声明了状态逻辑复杂时useReducer
的替代方法useState
useReducer
useState
当您具有包含多个子值的复杂状态逻辑或下一个状态取决于上一个值时,通常更可取。useReducer
还可以让您优化触发深层更新的组件的性能,因为您可以传递调度而不是回调。
什么这些钩子一样useContext
,useReducer
做的是,他们消除对依赖Redux
于小型的应用程序。
for*_*d04 19
1.)
useReducer
是作为 Redux 的替代品吗?
让我们澄清一下 Redux 是什么,这样我们就可以将它的主要部分与普通的 React 解决方案进行比较useReducer
:
(受本文启发)
import { useReducer, useContext, useMemo } from "react"
import { rootReducer } from "./reducers"
const GlobalContext = React.createContext()
const Provider = ({ children }) => {
const [state, dispatch] = useReducer(rootReducer, { count: 0 });
const store = useMemo(() => [state, dispatch], [state]);
// You can also separate dispatch and state context providers
return (
<GlobalContext.Provider value={store}>{children}</GlobalContext.Provider>
);
};
// Provider is placed at top-level to emulate a global state store
ReactDOM.render(<Provider> <App /> </Provider>, document.getElementById('root'))
const Comp = () => {
// You can extract this UI logic in its own custom hook for better encapsulation
const [state, dispatch] = useContext(GlobalContext);
// ...
};
Run Code Online (Sandbox Code Playgroud)
Redux 存储可以被实例化 ( createStore
) 并非常灵活地访问。使用 vanilla React,商店绑定到useReducer
UI 中的一个。我们可以通过上下文或道具传递它的状态。
rootReducer
与 Redux完全相同的纯函数用于 vanilla。
redux-thunk
并且redux-saga
是Redux中两个最流行的异步操作和副作用中间件。使用useReducer
,我们没有任何内置的中间件 API。相反,我们先进行异步处理,然后将结果转发到dispatch
:
const [state, dispatch] = useContext(GlobalContext);
// ...
<button onClick={() => dispatchAsync(dispatch)}> Process </button>
const dispatchAsync = dispatch => {
fetchData().then(data => dispatch({type: "increment"}, data))
};
Run Code Online (Sandbox Code Playgroud)
useReducer
只要涵盖了它们的通用 API,仍然可以将现有的 Redux 中间件与 集成- 您可以查看此答案以获取更多信息。
没有可用的直接集成useReducer
,因此您可能会在这里错过一个重要的工作流程工具。该复验库使用终极版DevTools也检查useState
和useReducer
(没有测试虽然)。
2.) 它是否更适合特定项目?它适合哪里?
useReducer
使用从本地状态和组件范围开始。如您所见,它也可以提升到全局范围以接管 Redux 的大部分角色。
在某些情况下,useReducer
甚至可以提供更大的灵活性,因为全局状态可以在多个上下文之间进行划分。示例:将不同状态树/上下文中的低优先级和高优先级状态更改分开。
使用 vanilla React,您将主要错过 Redux DevTools 和流行的中间件库。在另一方面功能,如combineReducers
可以很容易地重新实现了useReducer
,因为看到这里。
一般经验法则:开始为您的应用程序使用 vanilla React 并逐步添加诸如全局 Redux 存储之类的功能,一旦您觉得,这将成为强制性的(也取决于应用程序大小)。
import { useReducer, useContext, useMemo } from "react"
import { rootReducer } from "./reducers"
const GlobalContext = React.createContext()
const Provider = ({ children }) => {
const [state, dispatch] = useReducer(rootReducer, { count: 0 });
const store = useMemo(() => [state, dispatch], [state]);
// You can also separate dispatch and state context providers
return (
<GlobalContext.Provider value={store}>{children}</GlobalContext.Provider>
);
};
// Provider is placed at top-level to emulate a global state store
ReactDOM.render(<Provider> <App /> </Provider>, document.getElementById('root'))
const Comp = () => {
// You can extract this UI logic in its own custom hook for better encapsulation
const [state, dispatch] = useContext(GlobalContext);
// ...
};
Run Code Online (Sandbox Code Playgroud)
const [state, dispatch] = useContext(GlobalContext);
// ...
<button onClick={() => dispatchAsync(dispatch)}> Process </button>
const dispatchAsync = dispatch => {
fetchData().then(data => dispatch({type: "increment"}, data))
};
Run Code Online (Sandbox Code Playgroud)
useReducer
的状态仅针对单个组件-如果您想在整个应用中使用此状态,则需要dispatch
通过props向下传递它(和/或函数)。useState
实际上,它只是结构化的版本-实际上useState
是useReducer
在后台使用的!
另一方面,Redux可以做更多的事情-除其他功能外,它还可以通过上下文将状态提供给整个应用程序使用,然后提供API将深层嵌套的组件连接到该状态而无需传递道具。
换句话说:
useReducer
为您提供结构化的本地状态更新。如果你想“推出自己的终极版”与鱼钩,你需要使用的某种组合useReducer
和useContext
。
因此,如果要比较Redux和useReducer
Redux:
useReducer:
归档时间: |
|
查看次数: |
3570 次 |
最近记录: |