React-Admin提交表单后如何折叠编辑表单并刷新列表内容
解决React-Admin提交表单后刷新列表并折叠编辑栏的问题
你遇到的核心问题是异步操作的时序错误,以及没有利用React-Admin内置的状态/路由机制,反而直接操作window.location导致的异常。我来帮你一步步解决:
问题根源
crudCreate是异步操作,但你现在同步调用window.location.replace或reload,导致reload会在数据保存完成前就刷新页面,数据根本没存进去;- 单页应用中,
window.location.replace到同一个URL不会触发React-Admin的组件重新渲染,所以列表数据不会更新,编辑表单也不会折叠。
正确解决方案:利用React-Admin的异步回调与内置API
我们可以通过等待crudCreate完成,再触发列表刷新和路由跳转,完全不需要操作window.location。
步骤1:修改按钮的提交处理逻辑
在你的SaveWithNoteButtonView中,等待saveWithNote的异步操作完成后,再执行刷新和路由跳转:
import { connect } from 'react-redux'; import { refresh as refreshAction, crudCreate } from 'react-admin'; import { SaveButton } from 'react-admin'; const saveWithNote = (values, basePath, redirectTo) => crudCreate( 'usergrouprights', { ...values, GroupRights: CalcGroupPermissions(values).rights, GroupDenials: CalcGroupPermissions(values).denials }, basePath, { redirectTo } ); class SaveWithNoteButtonView extends Component { handleClick = () => { const { basePath, handleSubmit, redirect, saveWithNote, refresh, history } = this.props; return handleSubmit(values => { // 等待保存操作完成 return saveWithNote(values, basePath, redirect) .then(() => { // 1. 触发列表数据刷新(React-Admin内置动作) refresh(); // 2. 跳回列表页面,自动折叠编辑表单 history.push(basePath); }) .catch(err => { console.error('保存失败:', err); // 这里可以添加错误提示逻辑 }); }); }; render() { const { handleSubmitWithRedirect, saveWithNote, ...props } = this.props; return <SaveButton handleSubmitWithRedirect={this.handleClick} {...props} />; } } // 注入refresh动作和history对象 const SaveWithNoteButton = connect( undefined, { saveWithNote, refresh: refreshAction } )(SaveWithNoteButtonView); export default SaveWithNoteButton;
步骤2:确保redirect参数正确设置
在你的列表视图中使用自定义工具栏时,确保编辑表单的redirect属性指向列表路径(默认就是basePath,通常不需要额外设置),这样提交成功后会自动回到列表并折叠编辑栏。
为什么这个方案有效?
- 异步等待:通过
then()等待crudCreate完成,确保数据已经保存到后端再执行后续操作; - 内置refresh动作:React-Admin的
refresh会触发列表组件重新获取数据,更新视图,不需要页面重载; - 路由跳转:
history.push(basePath)利用React Router的单页路由机制,回到列表页面,同时触发编辑表单的折叠(因为编辑表单是列表的子组件,路由切换后会卸载/隐藏)。
额外优化:改用函数组件+Hooks(可选)
如果你愿意升级到函数组件,代码会更简洁:
import { useDispatch, useHistory } from 'react-router-dom'; import { SaveButton, useRefresh, crudCreate } from 'react-admin'; const saveWithNote = (values, basePath, redirectTo) => crudCreate( 'usergrouprights', { ...values, GroupRights: CalcGroupPermissions(values).rights, GroupDenials: CalcGroupPermissions(values).denials }, basePath, { redirectTo } ); const SaveWithNoteButton = props => { const dispatch = useDispatch(); const refresh = useRefresh(); const history = useHistory(); const { basePath, redirect } = props; const handleClick = () => props.handleSubmit(values => { return dispatch(saveWithNote(values, basePath, redirect)) .then(() => { refresh(); history.push(basePath); }); }); return <SaveButton handleSubmitWithRedirect={handleClick} {...props} />; }; export default SaveWithNoteButton;
这样完全抛弃类组件的写法,利用React-Admin和React Router的Hooks,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者Isabel Olson
相关产品推荐
相关产品推荐

