扫码一下
查看教程更方便
useRecoilTransaction()
创建一个事务回调,可用于以安全、简单和高效的方式自动更新多个原子。 为事务提供回调作为可以get()
或set()
多个原子的纯函数。 事务类似于设置 Recoil 状态的“更新器”形式,但可以在多个原子上操作。 写入对来自同一事务中的后续读取是可见的。
除了事务之外,这个钩子还可以用于:
useSetRecoilState()
。interface TransactionInterface {
get: <T>(RecoilValue<T>) => T;
set: <T>(RecoilState<T>, (T => T) | T) => void;
reset: <T>(RecoilState<T>) => void;
}
function useRecoilTransaction_UNSTABLE<Args>(
callback: TransactionInterface => (...Args) => void,
deps?: $ReadOnlyArray<mixed>,
): (...Args) => void
useCallback()
一样,生成的事务回调默认不会被记忆,并且会在每次渲染时生成一个新函数。 我们可以传递一个空数组以始终返回相同的函数实例。 如果在 deps 数组中传递值,则如果任何 dep 的引用相等性发生更改,将使用一个新函数。 然后可以在回调的主体中使用这些值而不会过时。 (请参阅 useCallback)我们可以更新 eslint 以帮助确保正确使用它。Transaction 接口:
假设我们有两个原子,positionState
和 headingState
,我们希望将它们一起更新为单个动作的一部分,其中 positionState
的新值是 positionState 和 headingState 的当前值的函数。
const goForward = useRecoilTransaction_UNSTABLE(({get, set}) => (distance) => {
const heading = get(headingState);
const position = get(positionState);
set(positionState, {
x: position.x + cos(heading) * distance,
y: position.y + sin(heading) * distance,
});
});
然后我们可以通过在事件处理程序中调用 goForward(distance)
来执行事务。 这将根据当前值更新状态,而不是渲染组件时的状态。
我们还可以在事务期间读取先前写入的值。 因为在更新程序执行时不会提交其他更新,所以我们将看到一致的状态存储。
const moveInAnL = useRecoilTransaction_UNSTABLE(({get, set}) => () => {
// Move Forward 1
const heading = get(headingState);
const position = get(positionState);
set(positionState, {
x: position.x + cos(heading),
y: position.y + sin(heading),
});
// Turn Right
set(headingState, heading => heading + 90);
// Move Forward 1
const newHeading = get(headingState);
const newPosition = get(positionState);
set(positionState, {
x: newPosition.x + cos(newHeading),
y: newPosition.y + sin(newHeading),
});
});
这个钩子对于实现 reducer
模式以在多个 atom
上执行操作也很有用:
const reducer = useRecoilTransaction_UNSTABLE(({get, set}) => action => {
switch(action.type) {
case 'goForward':
const heading = get(headingState);
set(positionState, position => {
x: position.x + cos(heading) * action.distance,
y: position.y + sin(heading) * action.distance,
});
break;
case 'turn':
set(headingState, action.heading);
break;
}
});
get()
的实现方式是一致的。await
的异步事务回调函数。但是,在事务返回的 Promise 完全解决之前,不会应用所有集合的原子更新。