Javascript useState钩子中的React setState在传递给RxJS子分区的回调中使用时导致异常

Javascript useState钩子中的React setState在传递给RxJS子分区的回调中使用时导致异常,javascript,reactjs,rxjs,react-hooks,Javascript,Reactjs,Rxjs,React Hooks,我正在编写一些帮助程序来简化React中RxJS的使用 我编写了一个自定义钩子,它允许您发送回调以订阅并从RxJS流获取更新,然后对其进行更新。这个钩子还允许您注册流错误和完成的回调。 这些在测试中正常工作,但在编写适当的示例时,React会在流错误上抛出一个错误,应该处理该错误,并在UI中显示消息 演示组件如下。请注意发生错误的行: export default ({subject})=>{ const [hasError, setHasError] = useState(fa

我正在编写一些帮助程序来简化React中RxJS的使用

我编写了一个自定义钩子,它允许您发送回调以订阅并从RxJS流获取更新,然后对其进行更新。这个钩子还允许您注册流错误和完成的回调。 这些在测试中正常工作,但在编写适当的示例时,React会在流错误上抛出一个错误,应该处理该错误,并在UI中显示消息

演示组件如下。请注意发生错误的行:

export default ({subject})=>{
    const [hasError, setHasError] = useState(false);
    const [complete, setComplete] = useState(false);
    const onError = (err)=>{
        setHasError(true); // <-------------- Commenting this line avoids the error!
        console.log('Value handled error',err);
    };
    const onComplete = ()=>{
        setComplete(true);
        console.log('Value handled completion');
    };
    const [val,setVal] = useSubject(subject,onError,onComplete);
    const onClick = ()=>setVal(val+1);
    return (
        <span>
            {val}
            {hasError?' An Error ocurred ':null}
            {complete?' Stream has completed ':null}
            <button onClick={onClick}>increment</button>
            <button onClick={()=>subject.error(5)}>Generate error</button>
            <button onClick={()=>subject.complete()}>Complete</button>
        </span>
    );
}
React的错误消息不是很有用,如果我理解正确,错误边界只会帮助我显示更好的UI,但我感兴趣的是修复错误,而不是包含它

当更新状态的行被注释掉后,回调可以正常工作并登录到控制台,而如果我在回调中更新状态(以便驱动UI更新),它就会崩溃。 我尝试了许多变通方法,并在钩子和组件之间转移责任,但最终我需要更新组件中的状态,这导致了崩溃。 奇怪的是,完成流也会通过一个非常类似的回调来更新状态,但这个回调是有效的


我做错了什么?它能得到帮助或解决吗?

在RxJS中,任何错误或完整的调用基本上都会“杀死”流。 在“示例”组件中
setHasError(true)
之后,它会重新呈现并再次运行此行:

const [val, setVal] = useSubject(subject, onError, onComplete);
这个钩子的开头是:

const [value, setValue] = useState(subject.getValue());

其中,出错主题上的getValue()会抛出一个错误。

Nice。我错过了这个,因为我专注于状态变化。出于同样的原因,subject.getValue应该始终小心执行。
const [value, setValue] = useState(subject.getValue());