使用react开发的经验总结(持续更新)

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}/>

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容