Rematch中dispatch后状态没更新是怎么回事?

A. 艳雯 阅读 5

我在用Rematch做状态管理,调用dispatch更新了state,但组件里拿到的还是旧值,render也没触发。是不是哪里写错了?

我试过在reducer里console.log新state,确实变了,但React组件就是不重新渲染。代码结构大概像这样:

const store = init({
  models: {
    user: {
      state: { name: 'Alice' },
      reducers: {
        setName: (state, payload) => ({ ...state, name: payload })
      }
    }
  }
});

// 组件里
const { name } = useSelector(state => state.user);
dispatch.user.setName('Bob');
我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
ლ东宁
ლ东宁 Lv1
这个问题很常见,我先说结论:你大概率是没用对Rematch的React绑定方式。

让我猜一下你的代码实际运行场景。你可能直接用了react-redux的useSelector,但Rematch需要配合它的React插件才能在函数组件里正常工作。

问题根源

Rematch本身是个状态管理库,但它不会自动和React组件绑定。你需要安装 @rematch/react 这个插件,并在初始化时注入进去。没有这个插件,store确实是更新了,但React根本不知道要重新渲染。

解决步骤

第一步,确保安装了依赖:

npm install @rematch/react


第二步,初始化时加上插件:

import { init } from '@rematch/core';
import { react } from '@rematch/react';

const store = init({
models: {
user: {
state: { name: 'Alice' },
reducers: {
setName: (state, payload) => ({ ...state, name: payload })
}
}
},
// 这里很关键,没有这行React不会触发更新
plugins: [react()]
});


第三步,在入口处用Provider包裹应用:

import { Provider } from 'react-redux';
import { useSelector, useDispatch } from '@rematch/react';

// 组件里这样写
function UserProfile() {
const { name } = useSelector(state => state.user);
const dispatch = useDispatch();

const handleClick = () => {
dispatch.user.setName('Bob');
};

return (
<div>
<p>当前名字: {name}</p>
<button onClick={handleClick}>改成Bob</button>
</div>
);
}

// 入口处
ReactDOM.render(
<Provider store={store}>
<UserProfile />
</Provider>,
document.getElementById('root')
);


这里需要注意一个常见坑

如果你用的是这种选择器写法:

const { name } = useSelector(state => state.user);


每次渲染时 useSelector 会返回一个新对象,虽然Rematch内部做了优化不会导致问题,但更稳妥的方式是这样写:

// 只取需要的具体值,避免对象重新创建
const name = useSelector(state => state.user.name);


还有一个可能的坑:你确认dispatch调用是异步的吗?如果在某些生命周期里同步调用后又立即读取state,确实可能拿到旧值,因为Redux的更新是批处理的。不过从你的描述看,更可能是插件没配的问题。

你先检查一下有没有按我说的第二步把 plugins: [react()] 加上去,十有八九是漏了这个。
点赞
2026-03-13 14:00