Когда я нажимаю на узел, я отправляю запрос API, который приносит мне все дочерние узлы, которые мне нужно отрендерить.
Я реализовал эту функцию, но есть ошибка производительности.Когда я щелкаю по узлу, мне нужно отобразить все его дочерние элементы И, чтобы скрыть все предыдущие выбранные дочерние узлы.Прямо сейчас ВСЕ выбранные дочерние узлы остаются в DOM.
Вот компонент Node:
@withRouter
@inject('dataStore')
@observer
class Node extends Component {
constructor() {
super()
this.state = {
myChildren: [],
myPath: 'root',
isChildrenShow: false
};
}
componentDidMount() {
this.mounted = true
}
componentWillUnmount(){
this.mounted = false
}
handleOnNodeClick = (e, node) => {
e.stopPropagation()
const {dataStore, history} = this.props
if(node.type === 1){
dataStore.setMainPicture(node.url)
history.push('/picture')
}
dataStore.getNodeChildren(this.props.myPath)
.then((res) => {
if(this.mounted){
this.setState({myChildren: res ? res.data.data.children : []})
}
})
}
render() {
const {dataStore, node, history} = this.props
return (
<ul>
<li onClick={(e) => this.handleOnNodeClick(e, node)}
className={this.props.node.type === 0 ? 'folder-node' : 'picture-node'}>
<h4 className="pointer" onClick={this.handleOnClick}>{node.label}</h4>
{
this.state.myChildren && this.state.myChildren.map(child => (
<div key={child.label}>
<Node
myPath={this.props.myPath + '/' + child.label}
node={child}
dataStore={dataStore}
history={history}
/>
</div>
))
}
</li>
</ul>
);
}
}
@withRouter
@inject('dataStore')
@observer
class RootNode extends Component {
state = {
myChildren: [],
};
handleOnClick = () => {
const {dataStore} = this.props
dataStore.getNodeChildren('root')
.then((res) => this.setState({myChildren: res ? res.data.data.children : []}))
}
render() {
const {dataStore, history} = this.props
return (
<div>
<div className="root-folder" onClick={this.handleOnClick}/>
{
this.state.myChildren && this.state.myChildren.map(child => (
<div key={child.label}>
<Node
myPath={'root/' + child.label}
node={child}
dataStore={dataStore}
history={history}
/>
</div>
))
}
</div>
)
}
}
export default RootNode;
Вот магазин:
import {observable, action, runInAction} from "mobx";
import axios from 'axios'
import Data from "../models/Data";
export default class DataStore {
@observable url = 'http://dvns.me/yaniv/clientest/public/explorePictures'
@observable selectedNode = null
@observable myChildren = []
@observable loadChildrenError = null
@observable pictures = []
@observable mainPicture = null
_config = {
headers: {
'X-TOKEN': '2d4e69f4823176197ccf41caa5ee6456',
}
}
@action
setMainPicture = (pic) =>{
this.mainPicture = pic
}
@action
async getNodeChildren(link) {
console.log('here, sending ajax to: ', link)
try {
const response = await axios(`${this.url}?path=${link}`, this._config)
runInAction(() => this.selectedNode = Data.reconstituteFrom(response.data.data))
runInAction(() => this.getPicturesFromNode(this.selectedNode))
return response
}
catch (e) {
console.log('Error! ', e.message)
runInAction(() => this.loadChildrenError = e.message);
}
finally {
// console.log('Selected Node From store ', this.selectedNode)
console.log('Pics From store ', this.pictures)
}
}
@action.bound
getPicturesFromNode = (node) => {
node.children.filter(child => {
if(child.type === 1){
this.pictures.push(child.url)
}
})
}
}
Репозиторий проекта: https://github.com/RomanDrevo/devsense