我正在用React构建一个 Treeview 应用程序,但有一些我没有解决的问题。
当我单击应用按钮时,我想将所有选择的值压入一个数组,但是当我单击取消按钮时,我要删除所有最后选择的值。< / p>
我的代码如下,请有人可以修改代码并为该解决方案提供帮助吗?
export default class TreeView extends Component {
constructor(props) {
super(props);
this.state = {
checked: [],
expanded: [],
keyword:"",
pushOn:[],
};
}
onSearchInputChange = (event, data, searchedNodes) => {
this.setState(prevState => {
if (prevState.keyword.trim() && !data.value.trim()) {
return {
expanded: [],
keyword: data.value
};
}
return {
expanded: this.getAllValuesFromNodes(searchedNodes, true),
keyword: data.value
};
});
};
getHighlightText = (text, keyword) => {
const startIndex = text.indexOf(keyword);
return startIndex !== -1 ? (
<span>
{text.substring(0, startIndex)}
<span style={{ color: "#2cb664" }}>
{text.substring(startIndex, startIndex + keyword.length)}
</span>
{text.substring(startIndex + keyword.length)}
</span>
) : (
<span>{text}</span>
);
};
keywordFilter = (nodes, keyword) => {
let newNodes = [];
for (let n of nodes) {
if(n.children) {
const nextNodes = this.keywordFilter(n.children, keyword);
if (nextNodes.length > 0) {
n.children = nextNodes;
} else if (n.label.toLowerCase().includes(keyword.toLowerCase())) {
n.children = nextNodes.length > 0 ? nextNodes : [];
}
if (
nextNodes.length > 0 ||
n.label.toLowerCase().includes(keyword.toLowerCase())
) {
n.label = this.getHighlightText(n.label, keyword);
newNodes.push(n);
}
}else {
if(n.label.toLowerCase().includes(keyword.toLowerCase())) {
n.label = this.getHighlightText(n.label, keyword);
newNodes.push(n);
}
}
}
return newNodes;
};
getAllValuesFromNodes = (nodes, firstLevel) => {
if (firstLevel) {
const values = [];
for (let n of nodes) {
values.push(n.value);
if(n.children) {
values.push(...this.getAllValuesFromNodes(n.children, false));
}
}
return values;
} else {
const values = [];
for (let n of nodes) {
values.push(n.value);
if(n.children) {
values.push(...this.getAllValuesFromNodes(n.children, false));
}
}
return values;
}
};
shouldComponentUpdate(nextProps, nextState) {
if(this.state.keyword !== nextState.keyword) {
return true;
}
if ( !lodash.isEqual(this.state.checked, nextState.checked)) {
return true;
}
if ( !lodash.isEqual(this.state.expanded, nextState.expanded)) {
return true;
}
return true;
}
render () {
let searchedNodes = this.state.keyword.trim()
? this.keywordFilter(lodash.cloneDeep(nodesData), this.state.keyword)
: nodesData;
return (
<div style={{marginLeft:"30px", marginTop:"30px", width:"30%"}}>
<div className="search">
<Input style={{marginBottom:"10px", width:"100%"}}
icon="fas fa-search"
placeholder="Search Categories"
iconPosition="left"
onChange={(event, data) => {
this.onSearchInputChange(event, data, searchedNodes);
}}
className="Change"
/>
</div>
<hr></hr>
<div className="checkbox-tree">
<CheckboxTree
nodes={searchedNodes}
checked={this.state.checked}
expanded={this.state.expanded}
onCheck={checked => this.setState({ checked })}
onExpand={expanded => this.setState({ expanded })}
expandOnClick
onClick = { () => { console.log("clicked"); }}
showNodeIcon={false}
icons={{
expandClose: <i class="fas fa-chevron-right fa-xs"></i>,
expandOpen: <i class="fas fa-chevron-down fa-xs"></i>,
}}
nameAsArray={true}
/>
</div>
<div>
<form class="butt">
<button type="button" onClick={this.cancel}>Cancel</button>
<button onClick={this.pushOnArray}>Apply</button>
</form>
</div>
</div>
)
}
}
谢谢!
答案 0 :(得分:0)
所以我不知道您的项目设置是什么,但是最简单的方法是:
export default class TreeViewParent extends Component {
constructor(props) {
super(props);
this.state = {
checked: [],
};
onSave = (newCheckedValues) => {
this.setState({checked: newCheckedValues})
// perform action based on selected values here
}
render() {
return <TreeView checked={this.state.checked} save={this.onSave} />
}
}
// I am omitting parts of this component that are not related to the problem
export default class TreeView extends Component {
constructor(props) {
super(props);
this.state = {
checked: this.props.checked,
expanded: [],
keyword: "",
pushOn:[],
};
}
cancel = () => {
this.props.save(this.props.checked)
this.setState({checked: this.props.checked})
}
save = () => {this.props.save(this.state.checked)}
render () {
let searchedNodes = this.state.keyword.trim()
? this.keywordFilter(lodash.cloneDeep(nodesData), this.state.keyword)
: nodesData;
return (
<div style={{marginLeft:"30px", marginTop:"30px", width:"30%"}}>
<div className="search">
<Input style={{marginBottom:"10px", width:"100%"}}
icon="fas fa-search"
placeholder="Search Categories"
iconPosition="left"
onChange={(event, data) => {
this.onSearchInputChange(event, data, searchedNodes);
}}
className="Change"
/>
</div>
<hr></hr>
<div className="checkbox-tree">
<CheckboxTree
nodes={searchedNodes}
checked={this.state.checked}
expanded={this.state.expanded}
onCheck={checked => this.setState({ checked })}
onExpand={expanded => this.setState({ expanded })}
expandOnClick
onClick = { () => { console.log("clicked"); }}
showNodeIcon={false}
icons={{
expandClose: <i class="fas fa-chevron-right fa-xs"></i>,
expandOpen: <i class="fas fa-chevron-down fa-xs"></i>,
}}
nameAsArray={true}
/>
</div>
<div>
<form class="butt">
<button type="button" onClick={this.cancel}>Cancel</button>
<button onClick={this.pushOnArray}>Apply</button>
</form>
</div>
</div>
)
}
另外,我看到您在不了解React基础知识的同时使用了诸如cloneDeep之类的“高级”东西。我建议您阅读react docs,因为我提供的答案是react的入门级概念。