2017-09-12 2 views
0

J'ai mis en place un menu latéral qui a un lien pour chaque section, mais je ne sais pas comment implémenter la fonctionnalité en cliquant dessus, l'utilisateur est amené à la section spécifique. Je comprends comment faire si c'était dans le même composant et si je produisais les sections de façon normale mais je le fais d'une manière différente et je ne sais pas comment implémenter quelque chose comme le scroll-scroll ou le scroll-scroll.Cliquez sur le lien pour faire défiler jusqu'à la section spécifique react.js

Ici, je génère les sections avec buildTree en mappant certaines données que j'ai dans un autre fichier.

export default class CheckboxGroup extends PureComponent { 
 
    constructor(props) { 
 
    super(props); 
 
    this.checkboxState = new Map(); 
 
    this.state = { 
 
     checkboxState: new Map(), 
 
    }; 
 
    } 
 

 
    static propTypes = { 
 
    data: PropTypes.any.isRequired, 
 
    onChange: PropTypes.func.isRequired, 
 
    counter: PropTypes.number, 
 
    }; 
 

 
    treeCheckboxOnChange = (parentLabel, id, checked) => { 
 
    this.checkboxState = this.checkboxState.setIn([parentLabel, id], checked); 
 
    this.setState({ 
 
     checkboxState: this.checkboxState, 
 
    }); 
 
    }; 
 

 
    mapParents = (counter, child) => { 
 
    const parentLabel = child.get('label'); 
 
    return (
 
     <li key={child.get('name')} className='field'> 
 
     <SegmentHeader style={segmentStyle} title={child.get('label')} icon={child.get('icon')}> 
 
     <div className='fields' style={zeroMargin}> 
 
      <div className='four wide field'> 
 
      <TreeCheckbox 
 
       label={`Grant ${child.get('label')} Permissions`} 
 
       parentLabel={parentLabel} 
 
       counter={counter} 
 
       onChange={this.treeCheckboxOnChange} 
 
      /> 
 
      {child.get('items') && this.buildTree(child.get('items'), counter + child.get('name'), parentLabel)} 
 
      </div> 
 
      <div className='twelve wide field'> 
 
      <GrantDropdown checkboxState={this.state.checkboxState.get(parentLabel, new Map())} label={child.get('label')} childItems={child.get('items')}/> 
 
      </div> 
 
     </div> 
 
     </SegmentHeader> 
 
    </li> 
 
    ); 
 
    }; 
 

 
    mapDataArr = (counter, parentLabel) => (child) => (
 
    (counter === 0) ? 
 
     this.mapParents(counter, child) 
 
     : 
 
     <li key={child.get('name')}> 
 
     <TreeCheckbox label={child.get('label')} parentLabel={parentLabel} onChange={this.treeCheckboxOnChange}/> 
 
     {child.get('items') && this.buildTree(child.get('items'), counter + child.get('name'), parentLabel)} 
 
     </li> 
 
) 
 

 
    buildTree = (dataArr, counter, parentLabel) => (
 
    <ul key={counter} style={listStyle}> 
 
     {dataArr.map(this.mapDataArr(counter, parentLabel))} 
 
    </ul> 
 
) 
 

 
    render() { 
 
    return (
 
     <div className='tree-view'> 
 
     {this.buildTree(this.props.data, this.props.counter)} 
 
     </div> 
 
    ); 
 
    } 
 
}

J'ai utilisé la même technique pour la carte sur les données pour créer mon sidenav collant.

export default class SideNav extends Component { 
 

 
    static propTypes = { 
 
    data: PropTypes.any.isRequired, 
 
    counter: PropTypes.number, 
 
    }; 
 

 
    mapPermissionNames = (counter, child) => (
 
    <li key={child.get('name')}> 
 
     <Link>{child.get('label')}</Link> 
 
    </li> 
 
) 
 

 
    mapDataArr = (counter) => (child) => (
 
    (counter === 0) ? 
 
     this.mapPermissionNames(counter, child) 
 
     : 
 
     <li key={child.get('name')}> 
 
     <Link>{child.get('label')}</Link> 
 
     </li> 
 
) 
 

 
    buildTree = (dataArr, counter) => (
 
    <ul key={counter} style={listStyle}> 
 
     {dataArr.map(this.mapDataArr(counter))} 
 
    </ul> 
 
) 
 

 
    render() { 
 
    return (
 
     <div className='tree-view'> 
 
     {this.buildTree(this.props.data, this.props.counter)} 
 
     </div> 
 
    ); 
 
    } 
 
}

et c'est le parent où ils sont tous deux rendus.

export default class LocationPermissions extends AbstractSettingsComponent { 
 

 
    handlePermissionChange = (e, { value }) => { 
 
    this.updatePerson('locationPermissions', value); 
 
    } 
 

 
    updateCheckmarks = (id, checked) => { 
 
    const { currentPerson } = this.props; 
 
    if (checked && !currentPerson.get('permissions').includes(id)) { 
 
     this.updatePerson('permissions', id, true); 
 
    } else if (!checked && currentPerson.get('permissions').includes(id)) { 
 
     this.filterItem(['currentPerson', 'permissions'], id, 1); 
 
    } 
 
    } 
 

 
    render() { 
 
    const { currentPerson } = this.props; 
 
    return (
 
     <div> 
 
     <SegmentHeader icon='building' title='Location Permissions'> 
 
      <div className='two fields' style={zeroMarginBottom}> 
 
      <div className='field'> 
 
       <OptionSelector 
 
       label={`Grant ${this.getPerson()} permissions for...`} 
 
       options={this.getPermissionOptions()} 
 
       value={currentPerson.get('locationPermissions') || 0} 
 
       onChange={this.handlePermissionChange} 
 
       /> 
 
      </div> 
 
      {currentPerson.get('locationPermissions') === 2 && 
 
       <div className='field'> 
 
       <label>Grant Location Admin Permissions For</label> 
 
       <LocationMultiSelect name='Every' {...this.props}/> 
 
       </div> 
 
      } 
 
      </div> 
 
     </SegmentHeader> 
 
     <StickyContainer> 
 
     {currentPerson.get('locationPermissions') === 3 && 
 
      <div className='fields'> 
 
      <div className='three wide field'> 
 
       <Sticky style={{ paddingTop: '15px' }}> 
 
       <SideNav 
 
        data={permissionSections} 
 
        counter={0} 
 
       /> 
 
       </Sticky> 
 
      </div> 
 
      <div className='twelve wide field'> 
 
      <CheckboxGroup 
 
       data={permissionSections} 
 
       counter={0} 
 
       onChange={this.updateCheckmarks} 
 
      /> 
 
      </div> 
 
     </div> 
 
     } 
 
     </StickyContainer> 
 
     </div> 
 
    ); 
 
    } 
 
}

J'ai du mal à comprendre comment implémenter quelque chose comme réagir-défilement ou scrollchor ou balises de liens réagissent-routeur pour pouvoir cliquer sur la section et faites défiler jusqu'à cette section sur la page . Toute suggestion serait la bienvenue.

Répondre

0

j'ai pu simplement utiliser le chemin du navigateur pris en charge en faisant:

<a href={`#${child.get('label')}`}>{child.get('label')}</a>

puis simplement ajouter un identifiant à l'élément de liste.