- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 ReactJS 功能组件中构建一个简单的 FSM(有限状态机)。我在找at this这指定他们可以异步执行,其次他们可以合并状态更改。
在类组件中,您可以使用双参数 setState()
方法链接状态更改。但是 useState()
Hook 中没有该功能。
基本上我想知道是否可以根据指定的行为创建 FSM?我正在尝试尽可能地缩小示例
我对 setter 的使用做了一些限制,即它只会在以下情况下执行:
无论如何,我设置了我的初始状态,并且我有一个单独的 useEffect
Hook ,如下所示
const [fsmState, setFsmState] = useState(States.Initial)
useEffect(() => {
stateHandlers[fsmState]();
}, [fsmState]);
States
是一个enum
enum States {
Initial,
Unauthenticated,
Authenticated,
Processing
}
我定义stateHandlers
如下:
const stateHandlers: {
[key in States]: () => void | Promise<void>;
} = {
[States.Initial]: async () => {
// this may load authentication state from a store,
// for now just set it to Unauthenticated
setFsmState(State.Unauthenticated);
},
[States.SigningIn]: async () => {
const authToken = await loginToServer(signInState));
if (authToken.isValid()) {
setFsmState(State.Authenticated);
} else {
setFsmState(State.Unauthenticated);
}
},
[States.Authenticated]: () => { },
[States.Unauthenticated]: () => { },
}
对于事件处理程序,例如登录 我这样做(这基本上就是我问这个问题的原因。
const signinAsync = async (username: string, password: string) => {
if (fsmState !== States.Unauthenticated) throw Error("invalid state");
// would these two get set in order?
setSignInState({username,password})
setFsmState(State.SigningIn);
}
如前所述,双参数版本不可用,所以我不能这样做
setSignInState({username,password},
() => { setFsmState(State.SigningIn) } )
我只是想要一个简单的 TSX 实现来避免添加额外的库。但是,在我学习 TypeScript/React 的过程中,我仍在编写此代码。
最佳答案
是的,这是可能的。事实上,有一个著名的 FMS 库叫做 xstate https://github.com/davidkpiano/xstate .
更新状态将始终是异步的,因为这就是它的工作方式并且是正确的。在您的状态机处理程序中,您只需要确保转换是正确的。我已经可以看出您的实现已经朝着正确的方向前进。
const signinAsync = async (username: string, password: string) => {
if (fsmState !== States.Unauthenticated) throw Error("invalid state");
// would these two get set in order?
setSignInState({username,password})
setFsmState(State.SigningIn);
}
无法保证哪一个会先发生。您的实现应该处理所有情况,无论是 setSignInState 还是 setFsmState 先发生。这两个 Action 应该是独立的。如果你需要两者都在一个系列中,那么你需要将它们链接在回调或其他东西中。例如,使用 setState,您可以将第二个参数作为回调传递,该回调将在状态更新后调用。
this.setState({ title: event.target.value }, function() {
this.validateTitle(); // thid will happen after state update
});
关于javascript - 当像 FSM 和 useEffect 一样使用时,React 状态更新是否按顺序发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65855083/
我知道没有数组的 useEffect() 只在第一次渲染时运行回调。 那么useEffect(()=>{},[])和没有useEffect()的区别是什么。 我的意思是: function myCom
我的场景很少,我想了解渲染和性能方面的差异。 下面显示的示例是一个简单的函数,但请考虑一个更复杂的函数以及一个异步函数。 场景 1:定义函数并在 useEffect 中调用它。 useEffect((
我需要添加一些与 React 之外的对象交互的事件处理程序(以 Google map 为例)。 在这个处理函数内部,我想访问一些可以发送给这个外部对象的状态。 如果我将状态作为依赖项传递给效果,它可以
要限制 useEffect 在第一个渲染上运行,我们可以这样做: const isFirstRun = useRef(true); useEffect (() => { if (isF
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我的状态宽度随着窗口大小的调整而变化,showFilters作为 Prop 从true变为false。我想在卸载时删除监听器。因此,我为每个条件使用了三个 useState。那么,我可以做任何重构来在
我正在开发一个基于对象键管理字符串数组的函数。假设它看起来像这样: import React, { useState, useEffect } from "react"; import FieldCo
新的 React Hooks 功能很酷,但有时会让我感到困惑。特别是,我将此代码包装在 useEffect Hook 中: const compA = ({ num }) => { const [
我想将其转换为 useEffect钩: 代码 componentDidMount () { this.messagesRef.on('child_added', snapshot => {
这是我的代码部分。一切正常,但 eslint 给出错误。 React Hook useEffect has missing dependencies: 'dispatch' and 'getData'
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
在 React DOCs 中,关于 useEffect() 钩子(Hook),我们得到: “使用 useEffect 安排的效果不会阻止浏览器更新屏幕。” Tip Unlike componentDi
我一直试图了解何时取消订阅(useEffect 中的回调)被准确调用。 这是codepen链接:https://codepen.io/deen_john/pen/eYmNdMy 代码 : const
当对状态、效果、上下文等使用钩子(Hook)时,我这样做: import React, { useState, useEffect, useContext } from 'react'; 但是,我注意
我正在尝试像下面这样的 useEffect 示例: useEffect(async () => { try { const response = await fetch(`ht
我在我的 React 应用中构建了一个简单的点赞、书签功能。 const [liked, setLiked] = useState(); const [bookmarked, setBookmarke
我想了解为什么在代码块的底部使用 useEffect,以及它的用途。我认为它与组件生命周期和避免无限循环有关,但我无法完全理解它并全面了解这一切。如果有人能向我解释幕后发生的事情,以及 useEffe
useEffect(() => { return history.replace({ pathname: "path/A", }); }, []); useEffe
我是一名优秀的程序员,十分优秀!