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={d}>{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}/>
}
网友评论