折腾Antd Pro的Reactjs期间,之前就遇到:
一个父页面:
src/routes/Script/ScriptCreateEdit.js
<DragableEditableTable tableMode={this.state.tableMode} columns={this.columns} itemList={this.state.dialogList} onTableDataChange={this.syncDialogList} onTableModeChange={this.onTableModeChange} form={this.props.form} />
在元素更新后,但是默认通过props无法传递到子元素DragableEditableTable中。
后来通过父页面中调用:
this.forceUpdate()
解决了问题。
但是现在遇到了问题:
子元素DragableEditableTable中再次调用子元素EditableTable:
this.props.tableMode === DragableEditableTable.TableMode.DRAGABLE ? ( <DragableTable columns={commonColumns} itemList={this.props.itemList} footer={commonModeSelectorFooter} onDragableListChange={commonDataChange} /> ) : ( <EditableTable columns={commonColumns} itemList={this.props.itemList} footer={commonModeSelectorFooter} onEditableCellChange={commonDataChange} filterCellItemBeforeSave={this.filterCellItemBeforeSave} form={this.props.form} /> )
结果props的变化,无法传递过去:
而此处基本上清楚了,应该是redux的问题
所以需要去解决:
子元素调用其子元素,props或state无法更新的问题
要么是用redux的方式解决
要么是自己额外找办法解决。
antd pro redux
所以问题转换为:
如果在antd pro中使用redux传递参数
antd pro 如何传递props
好像都是用:this.props.dispatch 去跳转的?
不过我此处没有跳转,只是调用子页面
“@connect 是 js 的修饰符,是为了让代码看起来更加地简洁,@connect 其实就是 redux 中的 connect
具体解释你可以参见这里 https://stackoverflow.com/questions/32646920/whats-the-at-symbol-in-the-redux-connect-decorator
第二个问题是 取代 store.dispatch 的一个好习惯,是传递 prop 到 组件的方法。
再次请看这里的解释:
”
@connect是react-redux中,将React component连接到Redux store
而@本身是:装饰器decorator
Decorators make it possible to annotate and modify classes and properties at design time.
难道继续用:componentWillReceiveProps去检测props变化?
而之前已有代码中,都是:
export const getRouterData = app => { const routerConfig = { '/': { component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')), }, '/script/script-list': { component: dynamicWrapper(app, ['script'], () => import('../routes/Script/ScriptList')), },
然后每个页面中,再去再去用connect的:
@connect(({ script, topic, loading }) => ({ // @connect(({ script, topic}) => ({ script, topic, loading: loading.models.script, })) @Form.create() export default class ScriptList extends PureComponent { state = {
不过,此处遇到的是:
DragableEditableTable这个子元素,不是独立的页面,也不需要全部的props,只需要传入的
itemList={this.state.dialogList}
能否检测到变化,
以及
<EditableTable
columns={commonColumns}
itemList={this.props.itemList}
能检测到变化即可。
去试试,直接给EditableTable加上connect,(而不去router.js中加上那个wrap)看看效果
不过,此处已经发现,通过给EditableTable加上:
export default class EditableTable extends React.Component { componentWillReceiveProps(nextProps){ console.log("EditableTable componentWillReceiveProps: nextProps=", nextProps) console.log("this.props.itemList=", this.props.itemList) if (this.props.itemList) { this.setState({itemList: this.props.itemList}) console.log("updated this.state.itemList=", this.state.itemList) } }
从而使得:
能否检测到props中参数变化,而及时更新数据了:
所以,暂时就不去深究那个connect的事情了。
后续再去试试能否实现:
不用componentWillReceiveProps,而直接通过connect后,props自动检测到数据变化,触发update。
【后记】
后来发现,此处的更新的逻辑写错了,应该改为:
componentWillReceiveProps(nextProps){ console.log("EditableTable componentWillReceiveProps: nextProps=", nextProps) console.log("this.props.itemList=", this.props.itemList) console.log("nextProps.itemList=", nextProps.itemList) // if (this.props.itemList) { if (nextProps.itemList) { // this.setState({itemList: this.props.itemList}) this.setState({itemList: nextProps.itemList}) console.log("updated this.state.itemList=", this.state.itemList) } }
然后对于传入props的改动,才能更新到state上去: