Rematch中dispatch更新后组件没渲染,如何解决?

UI梓希 阅读 29

在用Rematch写一个登录功能时遇到问题,dispatch更新user状态后组件没重新渲染。我用createAction返回了Promise,但控制台没报错,状态也没变。

尝试过这样写action:

export const login = () => async () => {
  const data = await api.login();
  return { type: 'setUser', payload: data };
}

,但效果还是没变化。

是不是effects配置有问题?或者组件监听的方式不对?

我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
维通~
维通~ Lv1
问题在于你的action写法有问题,Rematch的effects应该直接返回数据而不是action对象。正确的写法是这样:

export const login = async (payload, rootState, { api }) => {
const data = await api.login();
return data;
}

然后在model里定义好setUser的reducer,让effects自动触发reducer更新状态。组件监听state变化的方式没问题的话,这样改完就应该能正常渲染了。

要是还有问题,检查下api.login()是不是真的返回了正确数据,别被后端坑了。
点赞 1
2026-02-19 20:02
Air-诗琪
你这个情况是典型的 Rematch action 返回格式错误导致的。按照规范,如果你要返回一个对象来触发 reducer,必须用 put 或者直接在 model 的 effects 里调用 reducer,而不是自己拼 type 字段。

你现在的写法

return { type: 'setUser', payload: data };


这是 Redux 原生的写法,在 Rematch 的 effects 里不生效,因为 Rematch 不会自动 dispatch 这个对象。

正确的做法是:

1. 把登录逻辑放在 model 的 effects 中
2. 通过 dispatch.user.setUser(data) 主动调用 reducer

比如你的 model 应该这样写:

const user = {
state: { userInfo: null },
reducers: {
setUser(state, payload) {
return { ...state, userInfo: payload }
}
},
effects: (dispatch) => ({
async login() {
const data = await api.login()
// 这里显式调用 reducer
dispatch.user.setUser(data)
// 如果需要返回数据也可以
return data
}
})
}


然后你在组件里调用:

dispatch.user.login()


只要 reducer 正确修改了 state,并且你在组件中通过 useSelectoruseModel 订阅了 user 状态,组件就会重新渲染。

另外确认下你在 store 配置里注册 model 时用了 init({ models }),别漏了 effects 插件(Rematch 默认带,但如果你自定义过 config 可能会出问题)。

总结:不要返回 { type, payload },要用 dispatch.xxx.yyy() 显式调用 reducer,这才是 Rematch 推荐的方式。
点赞 3
2026-02-12 18:03