Skip to content

Commit

Permalink
fix(Tree): bug when object is not extensible,close #2070
Browse files Browse the repository at this point in the history
Co-authored-by: 皆虚 <jiarui.xjr@alibaba-inc.com>
  • Loading branch information
jerryyxu and 皆虚 committed Sep 8, 2020
1 parent 989566c commit b70d9e6
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 10 deletions.
8 changes: 4 additions & 4 deletions docs/tree/demo/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ Using the dataSource generate tree structure, in addition to setting the key, la
````jsx
import { Tree } from '@alifd/next';

const data = [{
const data = Object.freeze([{
label: 'Component',
key: '1',
children: [{
children: [Object.freeze({
label: 'Form',
key: '2',
selectable: false,
Expand All @@ -32,15 +32,15 @@ const data = [{
key: '5',
disabled: true
}]
}, {
}), {
label: 'Display',
key: '3',
children: [{
label: 'Table',
key: '6'
}]
}]
}];
}]);

class Demo extends React.Component {
onSelect(keys, info) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"babel-runtime": "^6.26.0",
"classnames": "^2.2.3",
"hoist-non-react-statics": "^2.1.0",
"lodash.clonedeep": "^4.5.0",
"prop-types": "^15.6.0",
"react-lifecycles-compat": "^3.0.4",
"react-transition-group": "^2.2.1",
Expand Down
35 changes: 34 additions & 1 deletion src/tree-select/tree-select.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component, Children, isValidElement, cloneElement } from 'react';
import { polyfill } from 'react-lifecycles-compat';
import PropTypes from 'prop-types';
import cloneDeep from 'lodash.clonedeep';
import classNames from 'classnames';
import Select from '../select';
import Tree from '../tree';
Expand Down Expand Up @@ -37,7 +38,17 @@ const flatDataSource = props => {
_k2n[key] = _p2n[pos] = _v2n[value] = newItem;
return newItem;
});
loop(props.dataSource);

try {
loop(props.dataSource);
} catch (err) {
// 对immutable数据进行深拷贝处理
if ((err.message || '').match('object is not extensible')) {
loop(cloneDeep(props.dataSource));
} else {
throw err;
}
}
} else if ('children' in props) {
const loop = (children, prefix = '0') =>
Children.map(children, (node, index) => {
Expand Down Expand Up @@ -571,6 +582,27 @@ class TreeSelect extends Component {
}
}

isSearched(label, searchedValue) {
let labelString = '';

searchedValue = String(searchedValue);

const loop = arg => {
if (isValidElement(arg) && arg.props.children) {
Children.forEach(arg.props.children, loop);
} else {
labelString += arg;
}
};
loop(label);

if (labelString.length >= searchedValue.length && labelString.indexOf(searchedValue) > -1) {
return true;
}

return false;
}

searchNodes(children) {
const { searchedKeys, retainedKeys } = this.state;

Expand Down Expand Up @@ -667,6 +699,7 @@ class TreeSelect extends Component {
notFoundContent,
useVirtual,
} = this.props;

const { value, searchedValue, expandedKeys, autoExpandParent, searchedKeys } = this.state;

const treeProps = {
Expand Down
20 changes: 18 additions & 2 deletions src/tree/view/tree.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable max-depth */
import React, { Component, Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
import cloneDeep from 'lodash.clonedeep';
import { polyfill } from 'react-lifecycles-compat';
import cx from 'classnames';
import { func, dom, obj, KEYCODE } from '../../util';
Expand Down Expand Up @@ -162,6 +163,7 @@ const preHandleData = (dataSource, props) => {
if (!('isLeaf' in item)) {
item.isLeaf = !((children && children.length) || props.loadData);
}

item.isLastChild = parent ? [].concat(parent.isLastChild || [], index === data.length - 1) : [];

if (key === undefined || key === null) {
Expand Down Expand Up @@ -216,10 +218,24 @@ const getData = props => {
const { dataSource, renderChildNodes, children = [], useVirtual } = props;
let data = dataSource;

if ((renderChildNodes || useVirtual) && !(data && data.length)) {
if ((renderChildNodes || useVirtual) && !('dataSource' in props)) {
data = convertChildren2Data(children);
}
return data && data.length ? preHandleData(data, props) : preHandleChildren(props);

if (data) {
try {
return preHandleData(data, props);
} catch (err) {
// 对immutable数据进行深拷贝处理
if ((err.message || '').match('object is not extensible')) {
return preHandleData(cloneDeep(data), props);
} else {
throw err;
}
}
} else {
return preHandleChildren(props);
}
};

/**
Expand Down
14 changes: 11 additions & 3 deletions test/tree/index-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import '../../src/tree/style.js';
const TreeNode = Tree.Node;
const { hasClass, getOffset } = dom;

const dataSource = [
const dataSource = freeze([
{
label: '服装',
key: '1',
Expand Down Expand Up @@ -53,7 +53,7 @@ const dataSource = [
},
],
},
];
]);
const _k2n = createMap(dataSource);

class ExpandDemo extends Component {
Expand Down Expand Up @@ -1047,7 +1047,15 @@ function createDataSource(level = 2, count = 3) {
key: '0-0',
});
drill(dataSource, level, count);
return dataSource;
return freeze(dataSource);
}

function freeze(dataSource) {
return dataSource.map(item => {
const { children } = item;
children && freeze(children);
return Object.freeze(item);
});
}

function getAllLabels() {
Expand Down

0 comments on commit b70d9e6

Please sign in to comment.