当前位置:编程学习 > > 正文

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

时间:2022-01-17 01:58:54类别:编程学习

react怎么使用父组件

关于antd tree和父子组件之间的传值问题react 总结

项目需求:点击产品树节点时获取该节点的所有父节点,同时回填表格的搜索条件,完成搜索功能,搜索结果展示在下方的table中。

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

写了三个组件:

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

现在有个业务场景交互:在orderTree组件中点击树节点,获取当前节点以及所有的父节点的Id 放入一个对象arrKeys中,并在orderForm组件中使用(回填类型下拉选择框,objId对象作为查询接口的入参)

现在可以分部解决问题:

1.首先获取点击的树节点以及所有父节点的id ---arrKeys

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

2.在点击树节点获取当前节点以及所有父级节点之后,通过this.props.idObject(arrKeys)把 arrKeys传给父组件。

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

3.在tree组件和form组件中的componentDidMount生命周期中把整个组件传给父组件

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

4.form组件中的inquery方法:

react怎么使用父组件(关于antd tree和父子组件之间的传值问题react 总结)

现附上tree.js代码

  • import React, { Component } from 'react';
    import { connect } from 'dva';
    import { liider, 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 = {}; // 当前节点以及所有父节点的id
    let firstParentKey = {}; // 一级根节点的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: [], //默认展开一级根节点 props.commodity.defaultParentIdList
          searchValue: '',
          autoExpandParent: true,
        };
      }
      componentDidMount() {
        const { dispatch } = this.props;
        this.props.treeRef && this.props.treeRef(this); //挂载时把整个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);
          }
        }
      };
    
      //展开/收起节点时触发
      onExpand = expandedKeys => {
        this.setState({
          expandedKeys,
          autoExpandParent: true,
        });
      };
      //点击树节点时触发
      onSelect = (selectKeys, e) => {
        const { dispatch } = this.props;
        const {
          commodity: { treeData },
        } = this.props;
        let arrKeys = {};
        //只有节点选中了才执行代码 dataRef是自定义在TreeNode上添加的属性,可以获取当前节点的所有信息
        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) {
                //不区分大小写
                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}>
            <li>
              <Search style={{ marginBottom: 8 }} placeholder="Search" onChange={this.onChange} />
              <Tree
                onExpand={this.onExpand}
                onSelect={this.onSelect}
                expandedKeys={expandedKeys}
                autoExpandParent={autoExpandParent}
              >
                {loop(treeData)}
              </Tree>
            </li>
          </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);
          }
        );
      };
      //判断是否点击重置按钮
      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}>
              <li
                style={{ width: '350px', marginRight: '30px', boxShadow: '3px -3px 6px 0px #ccc6' }}
                className={style.antTreeBox}
              >
                <OrderTree idObject={this.getIdObject} treeRef={this.treeRef} />
              </li>
              <li style={{ flex: '1' }}>
                <OrderForm onRef={this.onRef} isReact={this.isReact} />
                <OrderTable />
              </li>
            </Card>
          </PageHeaderWrapper>
        );
      }
    }
    
    export default OrderPage;
    
  • 以上就是关于antd tree 和父子组件之间的传值问题(react 总结)的详细内容,更多关于antd tree 父子组件传值的资料请关注开心学习网其它相关文章!

    上一篇下一篇

    猜您喜欢

    热门推荐