關(guān)于antd tree和父子組件之間的傳值問(wèn)題(react 總結(jié))
項(xiàng)目需求:點(diǎn)擊產(chǎn)品樹(shù)節(jié)點(diǎn)時(shí)獲取該節(jié)點(diǎn)的所有父節(jié)點(diǎn),同時(shí)回填表格的搜索條件,完成搜索功能,搜索結(jié)果展示在下方的table中。

寫了三個(gè)組件:

現(xiàn)在有個(gè)業(yè)務(wù)場(chǎng)景交互:在orderTree組件中點(diǎn)擊樹(shù)節(jié)點(diǎn),獲取當(dāng)前節(jié)點(diǎn)以及所有的父節(jié)點(diǎn)的Id 放入一個(gè)對(duì)象arrKeys中,并在orderForm組件中使用(回填類型下拉選擇框,objId對(duì)象作為查詢接口的入?yún)ⅲ?/p>
現(xiàn)在可以分部解決問(wèn)題:
1.首先獲取點(diǎn)擊的樹(shù)節(jié)點(diǎn)以及所有父節(jié)點(diǎn)的id ---arrKeys



2.在點(diǎn)擊樹(shù)節(jié)點(diǎn)獲取當(dāng)前節(jié)點(diǎn)以及所有父級(jí)節(jié)點(diǎn)之后,通過(guò)this.props.idObject(arrKeys)把 arrKeys傳給父組件。

3.在tree組件和form組件中的componentDidMount生命周期中把整個(gè)組件傳給父組件

4.form組件中的inquery方法:

現(xiàn)附上tree.js代碼
import React, { Component } from 'react';
import { connect } from 'dva';
import { Divider, Modal, Table, message, Tag, Spin } from 'antd';
import router from 'umi/router';
import style from '../style.less';
import { Tree, Input } from 'antd';
const { confirm } = Modal;
const { TreeNode } = Tree;
const { Search } = Input;
let dataList = [];
let keysObj = {}; // 當(dāng)前節(jié)點(diǎn)以及所有父節(jié)點(diǎn)的id
let firstParentKey = {}; // 一級(jí)根節(jié)點(diǎn)的id
const intetorFun = (data, key, string) => {
if (string) {
firstParentKey = {
[data.param]: data.paramId,
};
}
if (data.children && data.children.length !== 0) {
data.children.forEach(item => {
if (item.id === key[0]) {
keysObj = {
[data.param]: data.paramId,
[item.param]: item.paramId,
...firstParentKey,
};
} else {
intetorFun(item, key);
}
});
}
return keysObj;
};
const getParentKey = (key, tree) => {
let parentKey = [];
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
parentKey = intetorFun(node, key, 'firstTime');
}
return parentKey;
};
//搜索用的
const getSearchKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.id === key)) {
parentKey = node.id;
} else if (getSearchKey(key, node.children)) {
parentKey = getSearchKey(key, node.children);
}
} else {
if (node.id === key) {
parentKey = node.id;
}
}
}
return parentKey;
};
@connect(({ commodity, loading, menu }) => ({
commodity,
loading: loading.effects['commodity/getTree'],
menu,
}))
class OrderTree extends Component {
constructor(props) {
super(props);
this.state = {
expandedKeys: [], //默認(rèn)展開(kāi)一級(jí)根節(jié)點(diǎn) props.commodity.defaultParentIdList
searchValue: '',
autoExpandParent: true,
};
}
componentDidMount() {
const { dispatch } = this.props;
this.props.treeRef && this.props.treeRef(this); //掛載時(shí)把整個(gè)tree組件傳給父組件
dispatch({
type: 'commodity/getTree',
callback: res => {
this.generateList(res.data);
const defaultParentIdList = res.data.map(item => item.id);
this.setState({
expandedKeys: defaultParentIdList,
});
},
});
}
generateList = data => {
const { dispatch } = this.props;
for (let i = 0; i < data.length; i++) {
const node = data[i];
const { id, name } = node;
dataList.push({ id, name });
dispatch({
type: 'commodity/save',
payload: {
dataList,
},
});
if (node.children) {
this.generateList(node.children);
}
}
};
//展開(kāi)/收起節(jié)點(diǎn)時(shí)觸發(fā)
onExpand = expandedKeys => {
this.setState({
expandedKeys,
autoExpandParent: true,
});
};
//點(diǎn)擊樹(shù)節(jié)點(diǎn)時(shí)觸發(fā)
onSelect = (selectKeys, e) => {
const { dispatch } = this.props;
const {
commodity: { treeData },
} = this.props;
let arrKeys = {};
//只有節(jié)點(diǎn)選中了才執(zhí)行代碼 dataRef是自定義在TreeNode上添加的屬性,可以獲取當(dāng)前節(jié)點(diǎn)的所有信息
if (e.selected && e.node.props.dataRef.param !== 'categoryId') {
keysObj = {};
firstParentKey = {};
arrKeys = getParentKey(selectKeys, treeData);
} else if (e.selected && e.node.props.dataRef.param === 'categoryId') {
keysObj = {};
firstParentKey = {};
arrKeys = {
categoryId: e.node.props.dataRef.paramId,
};
} else if (!e.selected) {
return false;
}
this.props.idObject(arrKeys);
};
// 搜索功能
onChange = e => {
const { value } = e.target;
const {
commodity: { treeData, dataList, defaultParentIdList },
} = this.props;
let expandedKeys = [];
if (value) {
expandedKeys = dataList
.map(item => {
if (item.name.toLowerCase().indexOf(value.toLowerCase()) > -1) {
//不區(qū)分大小寫
return getSearchKey(item.id, treeData);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
this.setState({
expandedKeys,
searchValue: value,
autoExpandParent: true,
});
} else {
this.setState({
expandedKeys: defaultParentIdList,
searchValue: '',
autoExpandParent: true,
});
}
};
render() {
const { searchValue, expandedKeys, autoExpandParent } = this.state;
const {
commodity: { treeData },
loading,
} = this.props;
const loop = data =>
data.map(item => {
const index = item.name.toLowerCase().indexOf(searchValue.toLowerCase()); //忽略大小寫
const beforeStr = item.name.substr(0, index);
const afterStr = item.name.substr(index + searchValue.length);
const centerStr = item.name.substr(index, searchValue.length);
const title =
index > -1 ? (
<span title={item.name}>
{beforeStr}
<span style={{ color: '#f50' }}>{centerStr}</span>
{afterStr}
</span>
) : (
<span title={item.name}>{item.name}</span>
);
if (item.children) {
return (
<TreeNode key={item.id} title={title} dataRef={item}>
{loop(item.children)}
</TreeNode>
);
}
return <TreeNode key={item.id} title={title} dataRef={item} />;
});
return (
<Spin spinning={loading}>
<div>
<Search style={{ marginBottom: 8 }} placeholder="Search" onChange={this.onChange} />
<Tree
onExpand={this.onExpand}
onSelect={this.onSelect}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
>
{loop(treeData)}
</Tree>
</div>
</Spin>
);
}
}
export default OrderTree;
父組件index.js代碼:
import React, { Component } from 'react';
import { connect } from 'dva';
import { formatMessage, FormattedMessage } from 'umi/locale';
import { Card, Spin } from 'antd';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import OrderForm from './components/form';
import OrderTable from './components/table';
import OrderTree from './components/tree';
import style from './style.less';
import { consoleTestResultHandler } from 'tslint/lib/test';
// let dataList = [];
@connect(({ commodity, loading, menu }) => ({
commodity,
loading: loading.effects['commodity/getTree'],
menu,
}))
class OrderPage extends Component {
constructor() {
super();
this.state = {
idObject: {},
reactFlag: false,
};
}
componentDidMount() {
const { dispatch } = this.props;
dispatch({
type: 'commodity/getGoodsCategory',
});
}
onRef = ref => {
this.orderForm = ref;
};
treeRef = ref => {
this.orderTree = ref;
};
getIdObject = data => {
this.setState(
{
idObject: data,
},
() => {
this.orderForm.props.form.setFieldsValue({
categoryIds: [String(data.categoryId)],
});
this.orderForm.inquery(data);
}
);
};
//判斷是否點(diǎn)擊重置按鈕
isReact = ref => {
const {
commodity: { defaultParentIdList },
} = this.props;
if (ref) {
this.orderTree.setState({
expandedKeys: defaultParentIdList,
});
}
};
render() {
return (
<PageHeaderWrapper logo>
<Card bordered={false} title="商品SPU列表" className={style.antCardBox}>
<div
style={{ width: '350px', marginRight: '30px', boxShadow: '3px -3px 6px 0px #ccc6' }}
className={style.antTreeBox}
>
<OrderTree idObject={this.getIdObject} treeRef={this.treeRef} />
</div>
<div style={{ flex: '1' }}>
<OrderForm onRef={this.onRef} isReact={this.isReact} />
<OrderTable />
</div>
</Card>
</PageHeaderWrapper>
);
}
}
export default OrderPage;
以上就是關(guān)于antd tree 和父子組件之間的傳值問(wèn)題(react 總結(jié))的詳細(xì)內(nèi)容,更多關(guān)于antd tree 父子組件傳值的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React找不到模塊“./index.module.scss”或其相應(yīng)的類型聲明及解決方法
這篇文章主要介紹了React找不到模塊“./index.module.scss”或其相應(yīng)的類型聲明及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09
react實(shí)現(xiàn)移動(dòng)端下拉菜單的示例代碼
這篇文章主要介紹了react實(shí)現(xiàn)移動(dòng)端下拉菜單的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
react項(xiàng)目中express動(dòng)態(tài)路由未能匹配造成的404問(wèn)題解決
本文主要介紹了react項(xiàng)目中express動(dòng)態(tài)路由未能匹配造成的404問(wèn)題解決,解決了白屏的問(wèn)題,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
從零開(kāi)始學(xué)習(xí)搭建React腳手架項(xiàng)目
這篇文章主要介紹了從零開(kāi)始學(xué)習(xí)搭建React腳手架項(xiàng)目,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
詳解React項(xiàng)目如何修改打包地址(編譯輸出文件地址)
這篇文章主要介紹了詳解React項(xiàng)目如何修改打包地址(編譯輸出文件地址),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03
使用React-Router實(shí)現(xiàn)前端路由鑒權(quán)的示例代碼
這篇文章主要介紹了使用React-Router實(shí)現(xiàn)前端路由鑒權(quán)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

