跟着网上的教程做一个 todoList 的应用,采用 Ant Design Pro 的模板建立,但教程中是大概 2019 年,AntD pro 中组件默认是类型组件,但现有的模版会生成函数式组件,并且很多默认内容会在 app.tsx 中定义,比如 layouts 文件夹之类。可以参考官网升级到 V5 的文章:升级到 V5 。
于是就是自己探索怎么用 Hooks 来解决需要用到 react-redux 的地方。在 AntD 里面内置了 dva ,所以就用 dva 的方式在 models 里面创建配置,这个不需要考虑是类型还是函数型。用例可以参考官网的例子。我的配置如下:
export default {
namespace: 'todo',
state: {
todoList:[]
},
effects: {
*getTodoList(_, { call, put }) {
const resData = yield call(getTodoList)
console.log(resData);
yield put({
type: 'setTodoList',
payload: resData
})
}
},
reducers: {
setTodoList(state, {payload}) {
return {
...state,
todoList: payload
}
}
}
}
然后在应用中如下使用两个 hooks,来达到函数组件与 redux 连接,也就是代替了原本类型组件所需要用到的 connect。
const dispatch = useDispatch()
let todoList = useSelector(state => state.todo.todoList)
useEffect(() => {
// const resData = todoList
// setData(resData)
dispatch({
type: 'todo/getTodoList',
payload: null
})
},[])
...
const handleFinish = async (value) => {
// const newData = await addTodoList(value)
// setData(newData)
addTodoList(value)
dispatch({
type: 'todo/getTodoList',
payload: null
})
setIsModalVisible(false);
value = ''
}
...
return (
<PageHeaderWrapper>
<ProTable
columns={columns}
rowKey="id"
search={false}
dateFormatter="string"
dataSource={todoList} // 表格数据
// request={async ()=>({data: await getTodoList()})}
headerTitle="Todolist"
toolBarRender={() => [
<Button type="primary" key="primary" onClick={showModal}>
<PlusOutlined />new todo
</Button>,
]}
/>
<Modal title="Create new todo" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel} footer={null}>
// handleFinish 提交表格
<ProForm onFinish={value => handleFinish(value)}>
<ProFormText name="todo" label="Todo" rules={[{required:true}]}/>
</ProForm>
</Modal>
</PageHeaderWrapper>
)
其实一开始我想用自定义的 Hooks,毕竟在官网的 model 介绍里也在升级后成为了:
一种基于
hooks范式的简易数据管理方案(部分场景可以取代dva),通常用于中台项目的全局共享数据。
然后在自己的 models 文件封装 useGetTodo,然后因为 Protable 组件中的 request 组件自己封装了 useRequest 的 Hook,而 Hook 的规则中说到:
不要在循环,条件或嵌套函数中调用 Hook,确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们。
所以自定义 Hooks 不能嵌套在其他 Hooks 中。算是自己没遇到过的 bug,长个记性。不过不用 request 而用 dataSource ,在加上 useDispatch 和 useSelector 的使用,应该也可以解决全局共享状态的问题。之后可以再尝试一下。AntD Pro 还封装了 useModel 这个 API,也拥有消费 model 的能力,下次一定。
巩固了一下 Hooks 的规则和使用,菜就多练吧^^