Effector事件处理后状态未更新,组件也没重渲染怎么办?
在React项目里用Effector控制表单输入状态,按文档写了个事件和效应函数。但当我触发事件后,发现状态值没变,输入框内容也没重渲染。代码逻辑看起来没问题,但控制台没报错,手动调用effect函数也没反应。
这是我的代码:
import { createEvent, createStore, sample } from 'effector';
// 定义事件和初始状态
const inputChange = createEvent();
const $inputValue = createStore('');
// 效应函数尝试更新状态
sample({
source: inputChange,
fn: (value) => value,
target: $inputValue,
});
// React组件里
const InputComponent = () => {
const setValue = useStore($inputValue);
return (
<input
value={setValue}
onChange={(e) => inputChange(e.target.value)}
/>
);
};
已经检查过事件确实被触发了,但状态就是没更新。是不是哪里没订阅对?或者Effector和React的结合方式哪里错了?
把组件里的useStore那行改成 const inputValue = useStore($inputValue) 就行了,状态更新和重渲染自然就有了。搞定。
sample的用法上,Effector 里sample是用来映射事件到另一个事件或效应函数的,但你的写法实际上是把事件直接映射到了状态本身,这就导致状态更新失败了。正确的做法是用
$inputValue.on(inputChange, (state, value) => value)来绑定事件和状态。这样每次触发inputChange事件时,状态才会正确更新。另外,React 组件里
useStore拿到的状态是一个响应式值,不要起名叫setValue,容易混淆,改成value更合适。这是修正后的代码:
顺便提醒一下,Effector 虽然强大,但用的时候一定要注意状态管理的边界问题,尤其是和 React 结合时。如果项目规模大了,状态太多太复杂,记得要做校验,避免出现莫名其妙的 bug。还有,输入框这种直接交互的地方,安全性也很重要,记得对用户输入做必要的过滤和转义,防止 XSS 攻击之类的。