1.頁面的跳轉攜帶參數的問題
我的頁面很多都會進行頁面的跳轉,而下一個頁面的信息都是跟上頁面相關聯的,及時我跳轉的頁面所需要的信息,在跳轉前的頁面都是存在的,所以我第一個想的方法就是在跳轉路由的時候,通過傳參的方式,進行數據的傳遞,所以我是用了location中的state來存儲我傳的數據.
const data=record;
? ? ? ? ? ? ? ? const path = {
? ? ? ? ? ? ? ? ? ? pathname:'/person/releaseDetial',
? ? ? ? ? ? ? ? ? ? state:{data},
這樣傳遞的數據,我直接在新的頁面通過this.props.history.location中把他取出來,這樣傳遞數據,雖然確實可以在新的頁面拿到并且進行渲染,但是問題是,如果進行刷新,我的數據將會丟失,只能返回上一頁,重新進入.所以這里的修改,采用拼接URL的方式.因為刷新不會改變的是路由的地址,所以我們采用跳轉路由通過拼接URL的方式,然后通過解析路由,在新頁面進行數據的請求.
const {id}=record;
than.props.dispatch(routerRedux.push({
pathname:`/person/druginfo/edit/${id}`,
? ? ? }))
router.js里面配置路由使這么寫
'/person/druginfo/:type/:id':{
component:dynamicWrapper(app, ['personrelease'], ()=>import('../routes/Person/PersonRelease/ReleaseInfo')),? ? ? },
在新的頁面進行解析路由,拿到我們需要的id,然后在本頁面進行數據請求
const pathToRegexp=require('path-to-regexp');
const match=pathToRegexp('/person/druginfo/:type/:id').exec(this.props.history.location.pathname)
this.props.dispatch({
type:'persondrug/getBase',
payload:{idCard:match[2],
},
});
2.父子組件之間的信息交流
子調父
父組件一般是向子組件傳遞數據,然后子組件拿到數據進行自己頁面的一個渲染,但是更多時候,我們需要將一些函數一起傳給子組件,比如:彈出一個Modal進行數據的填寫,然后關閉Model的這個操作我們需要父組件來控制,但是這個確定按鈕又是在子組件里面.這時候我們就需要將此類的函數向子組件傳遞.還有一種函數叫做回調函數,父組件什么時候需要傳遞回調函數給子組件呢,當父組件需要子組件的一些數據的時候,比如我們填好數據,點擊確定的時候將填寫好的數據返回給父組件,最終由父組件向后臺發送請求.
父控子
首先得明確一個問題,作為子組件一般我們不會再給他綁定model,因為我們遵守React的一個思想,就是一個Container,其余都是用作展示組件的component。而所謂的展示組件,就是他只接受數據和函數,而不進行相關的處理
① 父組件如何給子組件傳值和函數
②子組件如何返回數據給父組件
③如果我需要通過父組件來控制子組件的某些功能,怎么才能使用子組件的函數
父傳子代碼如下
在父組件我們要給子組件傳遞一個函數,用ref來綁定子組件
parentprops:{
title:'新增其他人員',
isVisible:false,
list:{},
name:'',
handleCancel:()=>
? ? ? ? ? ? ?? {
this.props.dispatch({
type:'otherpeople/changeVisibal',
payload:{isVisible:false},
? ? ? ? ? ? ? ? ?? })
? ? ? ? ? ? ?? },
onRef:(ref)=>{
this.ModalForm=ref
? ? ? ? ? ? ?? },
seachIdCard:(idCard)=>
? ? ? ? ? ? ?? {
this.props.dispatch({
type:'otherpeople/getBase',
payload:{
idCard,
? ? ? ? ? ? ? ? ? ? ?? },
? ? ? ? ? ? ? ? ?? });
? ? ? ? ? ? ?? },
? ? onRef :(ref) => {?
? ? ? ? ? ? ? ? ? ? ? ? this.ModalForm = ref
? ? ? ? ? ? ? ? ? ? },
<ModalFormparentprops={this.state.parentprops}/>
然后在子組建的componentDidMount里面綁定this
? ? ?componentDidMount(){
? ? ? ? ? this.props.parentprops.onRef(this)
? ? ? ? }
然后就在父組件里調用子組件的函數?
用法如下:?
this.ModalForm.check()?
3異步加載的antd Tree組件,設置了 defaultExpandAll 為true但是不起作用
應該是類似value和defaultValue的相似問題,而這個里defaultExpandAllRows?
就是像defaultValue那樣 只在第一次渲染的時候起作用
而很多時候我們的數據初始是空的
4.DatePick
// 限制可選日期范圍為,今天以前的日期不可選(今天仍可選)
disabledDate={
function disabledDate(current) {
// Can not select days before today
? ? return current && current.isBefore(moment(Date.now()).add(-1,'day'));
}
}
開始日期,結束日期
<DatePicker
? style={{width:'100%' }}? format="YYYY-MM-DD"
? disabledDate={currentDate =>
getFieldValue('validToDate') &&
moment(getFieldValue('validToDate')).isBefore(currentDate,'day')
}/>
<DatePicker
? style={{width:'100%' }}? format={dateFormat}? disabledDate={currentDate =>
getFieldValue('validFromDate') &&
moment(getFieldValue('validFromDate')).isAfter(currentDate,'day')
}/>
5.關于回傳數據(lov,select等等組件)
const {form } =this.props;
從lov的點擊事件獲取數據后如要放到表單中,某些字段需要初始化一下(getFieldDecorator)再setFieldsValue,否則會報警告
setFieldsValue
if (data) {
form.getFieldDecorator('materialId');
form.setFieldsValue({
nameZh: data.nameZh,
nameEn: data.nameEn,
materialTypeCode: data.materialTypeCode,
materialId: data.materialId,
});
}
6.Modal中的initialValue
1.當我們第一次點開Modal的時候, FormItem會得到一個initialValue,但是這個值只在組件掛載的時候執行了一次, 當我們再次打開Modal窗口的時候并不會更新。
好了發現問題所在了, 接下來就是解決了~
解決方法:
Modal窗口我們都有應用一個Visible來控制是否顯示, 我們只要利用這個值得變化就可以實現Modal組件的重新掛載了。
{
Visible&&<Modal....../>
}
7.Table組件rowSelection方法
<Table rowSelection={rowSelection} columns={columns} dataSource={data} />
在 <Table/> 組件中有 rowSelection={rowSelection} 方法,可以讓Table的第一列成為聯動的選擇框。
API中說到通過 rowSelection.selectedRowKeys 來控制選中項。比較坑的是,selectedRowKeys 控制的只是dataSource當前的順序編號。
一定要加上rowKey={record => record.id},唯一標識每一行的字段(可組合),且?selectedRowKeys?存的就是id才能正常顯示勾選狀態。后來經過多次調試發現很多BUG都跟一個參數有關,不然會導致聯動的選擇框狀態異常。
onSelectChange(selectedRowKeys,selectedRows) {
const {handelSelectRow}=this.props;
handelSelectRow(selectedRows);
this.setState({
selectedRowKeys:selectedRows.map(r=>r.num),
?? });
? }
<Table
rowSelection={{
selectedRowKeys,
onChange:this.onSelectChange,
? ? ?? }}
columns={columns}
dataSource={dataSource}
bordered
loading={loading}
scroll={{x:1600}}
pagination={pagination}
onChange={page=>onSearch(page)}
rowKey="num"
8.select下拉選擇器點擊時帶出多個數據
通常的select選擇器會點擊函數onSelect上只會帶出key和value,當是由于客戶需求,點擊時需要帶出其他數據。
我用dataRef={數據集合}把數據放到節點上。很多其他類似的情況都可以這么干。
queryFuzzyData({requestUrl,data}).then(result=>{
if(currentValue===value&&result) {
constres=[];
result.content.forEach(r=>{
res.push({
materialId:r.materialId,
nameZh:r.nameZh,
materialTypeCode:r.materialTypeCode,
salesUnit:r.packSize,
? ? ? ? ?? });
? ? ? ?? });
callback(res);
? ? ?? }
? ?? });
const options=data.map(d=><Optionkey={d.materialId}dataRef=lfb8e6o>{d.nameZh}</Option>);
<Select
showSearch
value={value}
defaultActiveFirstOption={false}
showArrow={showArrow}
filterOption={filterOption}
onSearch={this.handleSearch}
onChange={this.handleChange}
onSelect={onSelect}
notFoundContent={null}
>
{options}
</Select>? ? ? ? ? ? ? ? ? ? ? ??
handelSelect(data,option) {
const{form}=this.props;
const{dataref}=option.props;
if(dataref) {
form.getFieldDecorator('materialId');
form.setFieldsValue({
nameZh:dataref.nameZh,
materialTypeCode:dataref.materialTypeCode,
materialId:dataref.materialId,
salesUnit:dataref.salesUnit,
skuNum:dataref.skuNum,
? ?? });
?? }
? }
9.正確使用setState
react官方文檔中這樣介紹setState的
setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.
setState不會立即修改this.state,也就是說我們在調用setState的后,立即訪問this.state是不能取得最新的this.state的值的。這樣在一些特殊需求的時候可能會出現問題。但是我們可以通過使用setState回調函數的形式來使下面的代碼拿到最新的this.state的值。
updateState({target}) {
this.setState(prevState=>{
const updatedUser={...prevState.user, [target.name]:target.value};// 使用先前的state來構建新的state的值
doSomething(updatedUser);
return{user:updatedUser};
? });
}
10.React-router-dom 路由切換時,如何觸發 componentDidMount?
描述:
在react 項目中我們獲取遠程數據總是會放在 componentDidMount 里面做的。但是這樣的話只有在組件初始化的時候才會調用。
而有些路由類似于:
<Route path='/detail/:id' component={detail} />
然后我們有一些 用于跳轉的
<Link to="/detail/123"></Link>? <Link to="/detail/456"></Link>。。。componentDidMount(){const{ match,handleAjaxItem } =this.props;? ? handleAjaxItem(match.params.id);? }? render(){const{ item } =this.props;return(? ? ? <div className="site-content"><div className="container"><Item item={item}/></div></div>)? }
首次進入頁面例如 detail/123 的時候是沒問題,但往后切換到 detail/456 ,就不再走componentDidMount?了
解決方案有兩個:
1.componentWillReceiveProps,每次在這個函數做this.props和nextProps的相等判斷然后就可以調用想要調用的方法啦,但是(好像官網不推薦這么干了)
2.問題的本質是為我們這兩個路由頁面對應的都是一個detail組件,只要用key將組件加以區分,這樣react 就會知道這不是‘同一個組件’,于是會重新初始化,componentDidMount當然會再走一遍。我的方法是用函數把組件包裝一下
例如
// 這是正常的導出組件
exportdefaultDetail;
// 用函數包裝一下變成這樣
exportdefaultfunction(props) {
return<Detail{...props}key={props.match.params.id}/>
}