1. 程式人生 > 其它 >遍歷children_樹的深度遍歷應用:實現省市區級聯(react版)

遍歷children_樹的深度遍歷應用:實現省市區級聯(react版)

技術標籤:遍歷children

深度優先遍歷口訣

  • 訪問根節點
  • 對根節點的children挨個進行深度優先遍歷

7b68d1df3d34cfce4891e3b9bf9e4fbf.png
實現圖示
import React from 'react';

class ProvicesPage extends React.Component {

  constructor(props) {
   super(props) 
   this.state = {
     cityData: [],
     areaData: [],
     selectedProvice: '',
     selectedCity: '',
     selectedArea: '',
     data: [
       {
         name: '廣東省',
         children: [
           {
             name: '深圳市',
             children: [
               {name: '南山區'},
               {name: '福田區'},
               {name: '寶安區'}
             ]
           },
           {
             name: '廣州市',
             children: [
               {name: '天河區'},
               {name: '海珠區'},
               {name: '番禹區'}
             ]
           }
         ]
       },
       {
         name: '浙江省',
         children: [
          { 
            name: '杭州市',
            children: [
              {name: '上城區'},
              {name: '下城區'},
              {name: '西湖區'}
            ]
          },
          {
            name: '寧波市',
            children: [
              {name: '江北區'},
              {name: '北侖區'},
              {name: '鄞州區'}
            ]
          }
         ]
       }
     ]
   }
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        selectedProvice: this.state.data[0].name
      });
      if(this.state.selectedProvice) {
        const cityData = this.fnGetChildren(this.state.data, this.state.selectedProvice);
        this.setState({
          cityData,
          selectedCity: cityData[0]? cityData[0].name : ''
        });
        if(this.state.selectedCity) {
          const areaData = this.fnGetChildren(this.state.data, this.state.selectedCity);
          this.setState({
            areaData,
            selectedArea: areaData[0]? areaData[0].name : ''
          });
        }
      }
    }, 10);
  }

  onProviceChange = (e) => {
    const value = e.currentTarget.value;
    const cityData = this.fnGetChildren(this.state.data, value);
    const areaData = this.fnGetChildren(this.state.data, cityData[0].name);
    this.setState({
      cityData,
      areaData,
      selectedProvice: value
    });
  }
  onCityChange = (e) => {
    const value = e.currentTarget.value;
    const areaData = this.fnGetChildren(this.state.data, value);
    this.setState({
      areaData,
      selectedCity: value
    });
  }
  onAreaChange = (e) => {
    const value = e.currentTarget.value;
    this.setState({
      selectedArea: value
    })
  }
  fnGetChildren = (tree, targetName) => {
    let childrenData = [];
    const dfs = (node) => {
      if(!node) return;
      node.forEach(child => {
        if(child.name === targetName) {
          childrenData = child.children;
        }
        if(child.children) dfs(child.children)
      })
    }
    dfs(tree);
    return childrenData;
  }


  render() {
    const {data,cityData,areaData} = this.state;
    return (
      <>
        <label>省份</label>
        <select className="select-item" onChange={this.onProviceChange}>
          {data.map((item) => 
            <option value={item.name} key={item.name}>{item.name}</option>
          )}
        </select>
        <label>市</label>
        <select className="select-item" onChange={this.onCityChange}>
          {cityData.map(item =>
             <option value={item.name} key={item.name}>{item.name}</option>
          )}
        </select>
        <label>區</label>
        <select className="select-item" onChange={this.onAreaChange}>
          {areaData.map(item =>
            <option value={item.name} key={item.name}>{item.name}</option>
          )}
        </select>
      </>
    )
  }

}
export default ProvicesPage;