一屹徘、框架使用
antd pro component - EditableProTable 表單重置
受控情況之下婿禽,改變 dataSource之后盒犹,但是表格編輯組件還是記錄上次編輯狀態(tài)記錄的數(shù)據(jù)壮锻,沒有及時(shí)更新瞳收,解決辦法就是手動(dòng)更新表單(其實(shí)整個(gè)表格就是一個(gè)form)
// 聲明form實(shí)例
const [form] = Form.useForm();
console.log('打印formValues:',form.getFieldsValue());
<EditableProTable<OrderCargoDtoType>
// scroll={{ x: 1300 }}
rowKey="id"
columns={columnsArr(short_width, options, onSelect, onSearch)}
// request={requestTableData}
dataSource={dataSource}
pagination={pageConfig}
actionRef={tableRef}
//onChange={setDataSource}
rowSelection={{ ...rowSelection, checkStrictly: false }}
toolBarRender={() => {
return renderTableToolBar(save, handleExport, dataCensus, batch,openEdit);
}}
editable={{
form:form,
type: 'multiple',
.....
//這里是修改dataSource的地方,也是需要更新表單的地方
getData={(data: any) => {
modifyRowKeys.forEach((ele, index) => {
let i = dataSource.findIndex((item) => {
return item.id == ele;
});
for (let key in data) {
dataSource[i][key] = data[key];
}
});
setDataSource(dataSource);
//------------------就是這里:锪妗?紊帷!--------------
form.resetFields();
}}
二他挎、dva使用
新建js文件 為dva倉庫
設(shè)置名稱 namespace: 'company',
設(shè)置state: {
enumeration: '', // 獲取所有枚舉
options: optinons,
default: 0,
isExist: false,
user: '', //用戶信息
},
effects內(nèi)部為異步函數(shù) 不可修改state 需要put提交到reducers修改
*為省略寫法的箭頭函數(shù)
函數(shù)接收兩個(gè)參數(shù) {state},{ put, call}
state為倉庫數(shù)據(jù)筝尾,put為提交到同步方法,內(nèi)部為type函數(shù)名稱办桨,payload為提交參數(shù)
reducers內(nèi)部為同步方法筹淫,唯一修改state數(shù)據(jù)方法,需要disptch提交呢撞,兩個(gè)參數(shù)损姜,type:’company/changeCompany‘饰剥,type寫法為倉庫名/函數(shù)名,payload為提交參數(shù)
const CompanySelet = {
namespace: 'company',
state: {
enumeration: '', // 獲取所有枚舉
options: optinons,
default: 0,
isExist: false,
user: '', //用戶信息
},
effects:{
*getUser({state},{ put, call}){
const { data = {}}= yield call(getEmployeeWithCurrentUser);
yield put({
type:'setUser',payload:data
});
},
*getEnu({state},{ put, call}){
const { data = {}}= yield call(getEnums, params.join(','));
const res = {...data, ...list}
let obj = {}
let arr = []
for (const item of paramsMap) {
if(res[item]) {
arr = Object.keys(res[item]).map(key => {
return { code: res[item][key], desc: key }
})
obj[item] = arr
}
}
yield put({
type:'setEnu',payload:obj
});
}
},
reducers: {
changeCompany(state, action) {
//固定寫法 return 返回整體state
return {
...state,
isExist: action.payload || false,
};
},
},
};
export default CompanySelet;
組件內(nèi)使用
import { connect } from 'dva';
const 組件名 = (props) => {
this.props.dispatch({
type: 'company/getEnu',
payload:{a:1}
})
}
export default connect(({ company }) => ({ company}))(組件名);
// 重點(diǎn): 首次進(jìn)入網(wǎng)站摧阅,無法觸發(fā)effect方法汰蓉,需要在effect中使用try{}catch{}方法
三、antd pro proLayOut 菜單分割時(shí)
定義三級(jí)路由棒卷,使一級(jí)路由自動(dòng)匹配到三級(jí)路由顾孽,必須在三級(jí)路由最后面加上一級(jí)路由的path和重定向,如果設(shè)置component比规,為顯示當(dāng)前一級(jí)路由頁面
四若厚、antd pro proLayOut 菜單分割時(shí)
[React中setState如何同步更新 ]
同步更新策略
1.完成回調(diào)
setState函數(shù)的第二個(gè)參數(shù)允許傳入回調(diào)函數(shù),在狀態(tài)更新完畢后進(jìn)行調(diào)用蜒什,譬如:
[](javascript:void(0); "復(fù)制代碼")
this.setState({
load: !this.state.load,
count: this.state.count + 1 }, () => {
console.log(this.state.count);
console.log('加載完成')
});
[](javascript:void(0); "復(fù)制代碼")
2.Promise封裝結(jié)合async/await
其實(shí)這里就是JavaScript異步編程相關(guān)知識(shí)测秸,將上面回調(diào)寫法換成Promise
引入Promise來封裝setState:
setStateAsync(state) { return new Promise((resolve) => { this.setState(state, resolve)
});
}
setStateAsync 返回的是Promise對(duì)象,在調(diào)用時(shí)我們可以使用Async/Await語法來優(yōu)化代碼風(fēng)格:
[](javascript:void(0); "復(fù)制代碼")
async componentDidMount() {
await this.setStateAsync ({
count: this.state.count * 1 + 2
})
console.log(123, this.state.count)
await this.setStateAsync ({
count: this.state.count * 1 + 2
})
console.log(456, this.state.count)
[](javascript:void(0); "復(fù)制代碼")
3.直接使用操作異步函數(shù)async / await
此時(shí)每次await setState都會(huì)執(zhí)行一遍render方法
[](javascript:void(0); "復(fù)制代碼")
handleChange = async () => {
await this.setState({
count: this.state.count * 1 + 2
})
console.log(123, this.state.count)
await this.setState({
count: this.state.count * 1 + 2
})
console.log(456, this.state.count)
}
[](javascript:void(0); "復(fù)制代碼")
四灾常、setState參數(shù)詳解
state中定義count初始值為1乞封;
1.第一個(gè)參數(shù)為傳入對(duì)象;
[](javascript:void(0); "復(fù)制代碼")
handleChange = () => { this.setState({
count: this.state.count + 2 })
console.log(123, this.state.count) this.setState({
count: this.state.count + 2 })
console.log(456, this.state.count)
}
[](javascript:void(0); "復(fù)制代碼")
調(diào)用方法兩次輸出值為都為3岗憋;
React 出于性能方面的考慮肃晚,并不會(huì)直接對(duì)每次的調(diào)用都進(jìn)行更新,而是會(huì)將多次傳入的對(duì)象進(jìn)行合并處理仔戈,以產(chǎn)生一個(gè)新的最終的 state
對(duì)象关串;
第二個(gè)參數(shù)為完成回調(diào)
[](javascript:void(0); "復(fù)制代碼")
handleChange = () => { this.setState({
count: this.state.count + 2 }, () => {
console.log(123, this.state.count)
}) this.setState({
count: this.state.count + 2 }, () => {
console.log(456, this.state.count)
})
}
[](javascript:void(0); "復(fù)制代碼")
與上面輸出保持一致
2.第一個(gè)參數(shù)為傳入函數(shù):
[](javascript:void(0); "復(fù)制代碼")
handleChange = () => { this.setState((prevState, props) => ({
count: prevState.count + 2 }), () => {
console.log(123, this.state.count)
}) this.setState((prevState, props) => ({
count: prevState.count + 2 }), () => {
console.log(456, this.state.count)
})
}
[](javascript:void(0); "復(fù)制代碼")
函數(shù)第一個(gè)參數(shù)接收先前的狀態(tài)作為第一個(gè)參數(shù),將此次更新被應(yīng)用時(shí)的props做為第二個(gè)參數(shù)监徘;
此時(shí)輸出為兩次都是5晋修;
在第二次調(diào)用 setState 方法時(shí)便可以通過 prevState.count 拿到最新的值從而更新本次的 state 。顯然凰盔,React 對(duì)于傳入函數(shù)的方式和傳入對(duì)象的方式進(jìn)行更新 state 的各自具體理念是不一樣的墓卦,對(duì)于傳入函數(shù)的方式,在調(diào)用 setState 進(jìn)行更新 state 時(shí)户敬,React 會(huì)按照各個(gè) setState 的調(diào)用順序落剪,將它們依次放入一個(gè)隊(duì)列,然后尿庐,在進(jìn)行狀態(tài)更新時(shí)忠怖,則按照隊(duì)列中的先后順序依次調(diào)用,并將上一個(gè)調(diào)用結(jié)束時(shí)產(chǎn)生的 state 傳入到下一個(gè)調(diào)用的函數(shù)中抄瑟,當(dāng)然凡泣,第一個(gè) setState 調(diào)用時(shí),傳入的 prevState 則是當(dāng)前的 state ,如此鞋拟,便解決了傳入對(duì)象式調(diào)用 setState 方法所存在的 不能依賴上一次的 state 去計(jì)算本次 state 的問題骂维。
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background-color, border-color, border-radius, padding, margin, color, opacity; overflow: auto; font-family: "Courier New"; font-size: 12px; overflow-wrap: break-word;">handleChange = () => { this.setState((prevState, props) => ({
count: prevState.count + 2 }), () => {
console.log(123, this.state.count)
}) this.setState((prevState, props) => ({
count: this.state.count + 2 }), () => {
console.log(456, this.state.count)
})
}</pre>
](javascript:void(0); "復(fù)制代碼")
值得一提的是,在上面的這段代碼中贺纲,執(zhí)行第二個(gè) setState 里面的函數(shù)時(shí)席舍,由第一個(gè) setState 所產(chǎn)生的最新的 state 并沒有合并到 this 對(duì)象上面去,所以此時(shí)通過 this.state 獲取不到最新的狀態(tài)哮笆,故而在函數(shù)內(nèi)部拿到的 this.state.count 的值為 1 而非 3。
另外汰扭,不論第一個(gè)參數(shù)是何種類型稠肘,多次setState也只會(huì)調(diào)用一次render方法,第二個(gè)參數(shù)callback完成回調(diào)中獲取this.state的值同樣也是多次setState合并操作后的最終值萝毛;