用函数反应递归子组件

时间:2018-07-25 05:49:29

标签: function recursion components

请确保我可以制作递归子组件,但是父级功能无法到达递归子组件( NavLink.js 73&74 onClick )行组件。这是我的代码,我将其用于Role Base Access的嵌套导航。

App.js 父级

import React, { Component } from 'react';
import './App.css';
import $ from 'jquery';
import Footer from './Footer/Footer';
import Dashboard from './Dashboard/Dashboard';
import SNavigation from './Navigation/Side/SNavigation';
import MNavigation from './Navigation/Top/Mobile/MNavigation';

class App extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.state = {
      checkw:undefined,
      stepNumber: 0,
      currentPage: "Units",
      currentPageChild: null,
      App:[{
          profile: {
            name:"AJ",
            id:1,
            resources: [
            {
              name:"Dashboard"
            },
            {
                name:"Units",
                permissions:[{
                  to:"Create"
                },
                {
                  to:"Read"
                }]
            },
            {
                name:"Lessees",
                permissions:[{
                  to:"Create"
                },
                {
                  to:"Read"
                }]
            },
            {
              name:"Lessors",
              permissions:[{

                to:"Create"
              },
              {
                to:"Read"
              }]
            },
            {
              name:"Invoices",
              permissions:[{

                to:"Create"
              },
              {
                to:"Read"
              }]
            },
            {
              name:"Admin",
              permissions:[{
               to: "System Users",
              },
              {
               to: "Permissions",
              }]
            }]
          }
        }]
    };
  }
  handleClick(currentPage,currentPageChild) {

    this.setState({
        currentPage:currentPage,
        currentPageChild:currentPageChild
    });

    console.log(currentPage);
  }
  handleResize = () => {
      var w = $(window).width();

      if (typeof this.state.checkw === 'undefined'){
        this.setState({
          checkw:w
        });
      }
      
      if (w!==this.state.checkw) {
          if($('[rel="js-rms-page"]').hasClass('rms-page--transform')) {
        $('[rel="js-rms-page"]').removeClass('rms-page--transform');
        $('.hamburger').removeClass('is-active');
      }
      $('[rel="js-rms-page"]').css('min-height', $('html').height()); 
          // do your responsive magic!

         this.setState({
          checkw:w
         });
          
      }
  }

  componentDidMount() {
     this.handleResize();
     window.addEventListener('resize', this.handleResize)
  }

  componentWillUnmount() {
    window.removeEventListener('resize',this.handleResize)
  }

  render() {
    const App = this.state.App;
    const current = App[this.state.stepNumber];
    return(
        <div>
          <MNavigation profile={current.profile} />
          <main className="rms bg-dark clearfix">
            <SNavigation profile={current.profile} onClick={(value,currentPageChild) => this.handleClick(value,currentPageChild)} currentPageChild={this.state.currentPageChild} currentPage={this.state.currentPage}  /> {/* sidebar */}
            <div className="rms-page" rel="js-rms-page">
              <div className="scrollable">
                  <Dashboard /> {/* Page display here */}
                  <Footer /> {/* footer */}
              </div>
            </div>
          </main>
        </div>
        );
  }
}

export default App;

SNavigation.js :这是调用NavLink.js的侧面导航,基本上是li链接

import React, { Component } from 'react';
import './SNavigation.css';
import NavLink from '../../common/NavLink';

class SNavigation extends Component {
	constructor(props) {
    	super(props);
		this.props.onClick.bind(this);
	}

	render() {
		const {profile,currentPage,currentPageChild, onClick} = this.props;
		let node = profile.resources.map((resource) => {
				return (
					<NavLink key={resource.name} onClick={() => onClick(resource.name)} haveIcon value={resource.name} dataToggle="collapse" dataParent="#accordionSideNav"  currentPage={currentPage} currentPageChild={currentPageChild} permissions={resource.permissions}/>
				);
		});
		var nameInitialDiv = {
			height:'50px',
			width:'50px'
		};
		return(
			  <div className="rms-sidebar scrollable bg-dark">
			    <div className="container-fluid" id="accordionSideNav">
			    <ul className="nav flex-column">
			      <li className="nav-item active py-2">
			      <a href="#app" className="nav-link sidebar__link--light d-lg-block d-xl-block d-none">
			      	<h3 className="brand--font-style" title="rental management system">RMS</h3>
			      </a>
			      </li>
			      <li className="nav-item d-bock d-lg-none d-xl-none">
			          <ul className="nav align-items-center py-3 pl-0" style={{fontSize:'1rem'}}>
			            <li className="nav-item ml-auto">
			              <a className="nav-link sidebar__link--light pl-1 pb-0 m-auto" href="#app">
			                <div className="m-auto">
			                  <div style={nameInitialDiv} className="bg-info rounded-circle text-white d-flex flex-column align-items-center">
			                  <p className="m-auto text-white">AD</p>
			                  </div>
			                </div>
			              </a>
			            </li>
			            <li className="nav-item ml-auto">
			              <a className="nav-link sidebar__link--light pl-0 pb-0" href="#app"><i className="fa fa-bell"></i></a>
			            </li>
			            <li className="nav-item ml-auto">
			              <a className="nav-link sidebar__link--light  pl-0 pb-0" href="#app"><i className="fa fa-user"></i></a>
			            </li>
			            <li className="nav-item ml-auto">
			              <a className="nav-link sidebar__link--light pl-0 pb-0" href="#app"><i className="fa fa-power-off"></i></a>
			            </li>
			          </ul>
			      </li>
			      {node}
			    </ul>

			    {/*
				<h5 className="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
			      <p data-toggle="collapse" data-target="#collapseQL" className="d-flex cursor--pointer align-items-center text-muted"><i className="fa fa-plus-circle"></i><span className="ml-2">Quick Links</span></p>
			    </h5>
			    <ul className="nav mb-2 pl-0 collapse" id="collapseQL" data-parent="#collapseQL">
			      <li className="nav-item">
			        <a className="nav-link sidebar__link--light" href="#app"> Current month
			        </a>
			      </li>
			      <li className="nav-item">
			        <a className="nav-link sidebar__link--light" href="#app">
			          Last quarter
			        </a>
			      </li>
			      <li className="nav-item">
			        <a className="nav-link sidebar__link--light" href="#app">
			          Social engagement
			        </a>
			      </li>
			      <li className="nav-item">
			        <a className="nav-link sidebar__link--light" href="#app">
			          Year-end sale
			        </a>
			      </li>
			    </ul>
			    */}
			  </div>
			</div>
		);
	}
}

export default SNavigation;

NavLink.js 递归子组件

import React, { Component } from 'react';
import 'bootstrap/dist/js/bootstrap.min';
import $ from 'jquery';
class NavLink extends Component {
	getIcon(value) {
		switch(value) {
			case "Dashboard":
				return "fa-tachometer";
			break;
			case "Units":
				return "fa-building-o";
			break;
			case "Lessees":
				return "fa-user-circle";
			break;
			case "Lessors":
				return "fa-user-circle";
			break;
			case "Invoices":
				return "fa-calculator";
			break;
			case "Admin":
				return "fa-wrench";
			break;
			case "Create":
				return "fa-plus-square";
			break;
			case "Read":
				return "fa-list";
			break;
			case "Read":
				return "fa-list";
			break;
			case "System Users":
				return "fa-users";
			break;
			case "Permissions":
				return "fa-lock";
			break;
			default:
				return "fa-question-circle";
			break;
		}
	}

	componentShoudUpdate(){
		const {currentPage, value, currentPageChild} = this.props;
		console.log(currentPageChild);
	}
	componentDidUpdate(){
		const {currentPage, value,currentPageChild} = this.props;
		var id = "#collapse"+value;
		if(currentPage==="Dashboard") $(id).collapse('hide');
	}
	
	componentDidMount() {
		const {currentPage, value,currentPageChild} = this.props;
		var id = "#collapse"+value;
		if(value===currentPage) $(id).collapse('show');
	}

	render() {

		const {currentPage, onClick, className, currentPageChild, haveIcon, value, id, dataToggle, dataParent, childName, accordionId, permissions} = this.props;
		
		let childnodes = null;
		let _className = null;
		let _onClick = onClick, _dataTarget = '#collapse'+value;
		if(permissions){
			childnodes = this.props.permissions.map((permission) => {
				let _currentPageChild = permission.to;
				if(value==="Admin")
				return (<NavLink onClick={() => onClick(null,permission.to)} key={permission.to} haveIcon value={permission.to} currentPage={currentPage} currentPageChild={currentPageChild} />);
				return (<NavLink key={permission.to+" "+value} onClick={() => onClick(null,permission.to)} haveIcon currentPage={currentPage} childName={permission.to+" "+value} value={permission.to} currentPageChild={currentPageChild} />);
			});
		}
		_className = className;
		if(_className===undefined){
			_className='nav-link sidebar__link--light' + (permissions ? ' collapsed':'');
		}	
		if(currentPage===value || (currentPageChild+" "+currentPage)===childName){
			_onClick = null;
			_dataTarget = null;
		}
		return (
			<li className={'nav-item' + (currentPage===value || (currentPageChild+" "+currentPage)===childName ? ' active':'')}>
				<button onClick={_onClick} className={"btn btn-link "+_className} data-toggle={dataToggle} data-target={_dataTarget}>
					<i className={'fa ' + (haveIcon ? this.getIcon(value):'')}></i> {value} {(currentPage===value ? <span className="sr-only">(current)</span>:'')}
				</button>
				{ childnodes ? <ul className={"collapse list-unstyled"} id={"collapse"+value} data-parent={dataParent}>{childnodes}</ul>	: null }
			</li>
		);
	};
}

export default NavLink;

1 个答案:

答案 0 :(得分:0)

我能够更正序列,因此该功能应在递归组件子代上起作用。

因此,在 SNavigation.js 行#15上,我设置了onClick道具以传递来自父 App.js 行#126的onClick本身。然后在递归子组件上 NavLink.js 我在onClick道具行65上添加了一个值,也在行70和71上添加了一个参数,以便可以再次递归访问它并可以再次接受一个参数:)