点击链接滚动到特定部分react.js [英] Click link to scroll to specific section react.js

查看:88
本文介绍了点击链接滚动到特定部分react.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了一个侧面菜单,该侧面菜单的每个部分都有一个链接标签,但是我不确定如何在单击这些菜单时将用户带到特定部分。我知道如果它是在同一组件中并且如果我以正常方式生成这些节,但我以不同的方式来做,并且不确定如何实现类似react-scroll或scrollchor的方法,那么我该怎么做。 / p>

在这里,我通过映射我在另一个文件中拥有的某些数据来生成带有buildTree的部分。

 导出默认类CheckboxGroup扩展了PureComponent {
构造函数(props){
超级(props);
this.checkboxState = new Map();
this.state = {
checkboxState:new Map(),
};
}

静态propTypes = {
数据:PropTypes.any.isRequired,
onChange:PropTypes.func.isRequired,
计数器:PropTypes.number ,
};

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

mapParents =(计数器,孩子)=> {
const parentLabel = child.get(‘label’);
return(
< li key = {child.get('name')} className ='field'>
< SegmentHeader style = {segmentStyle} title = {child.get ('label')}图标= {child.get('icon')}>
< div className ='fields'style = {zeroMargin}>
< div className ='四个宽域'>
< TreeCheckbox
label = {`授予$ {child.get('label')}权限`}
parentLabel = {parentLabel}
counter = {counter}
onChange = {this.treeCheckboxOnChange}
/>
{child.get('items')&& this.buildTree(child.get('items') ,计数器+ child.get('name'),parentLabel)}
< / div>
< div className ='十二个宽字段'>
< GrantDropdown checkboxState = { this.state.checkboxState.get(parentLabel,new Map())} label = {child.get('label')} childItems = {child.get('items')} />
< / div>
< / div&g ;
< / SegmentHeader>
< / li>
);
};

mapDataArr =(counter,parentLabel)=> (孩子)=> (
(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键= {counter} style = {listStyle}>
{dataArr.map(this.mapDataArr(counter,parentLabel))}}
< / ul>


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

我使用相同的技术来映射数据创建我的粘性sideNav。

 导出默认类SideNav扩展了组件{

static propTypes = {
数据:PropTypes.any.isRequired,
计数器:PropTypes.number,
};

mapPermissionNames =(计数器,子级)=> (
< li key = {child.get('name')}>
< Link> {child.get('label')}< / Link>
< ; / li>


mapDataArr =(counter)=> (孩子)=> (
(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>
);
}
}

,这是它们都被渲染的父对象。

 导出默认类LocationPermissions扩展AbstractSettingsComponent {

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

updateCheckmarks =(id,已选中)=> {
const {currentPerson} = this.props;
if(选中&&!currentPerson.get(‘permissions’)。includes(id)){
this.updatePerson(’permissions’,id,true);
}否则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 ='两个字段'style = { zeroMarginBottom}>
< div className ='field'>
< OptionSelector
label = {`Grant $ {this.getPerson()}权限......}
选项= {this.getPermissionOptions()}
值= {currentPerson.get('locationPermissions')|| 0}
onChange = {this.handlePermissionChange}
/>
< / div>
{currentPerson.get('locationPermissions')=== 2&&
< div className ='field'>
< label> ;< / label>
< LocationMultiSelect name ='Every'{... this.props} />
< / div>
} $ b $的授予位置管理权限b< / div>
< / SegmentH eader>
< StickyContainer>
{currentPerson.get(’locationPermissions’)=== 3&&
< div className =字段>
< div className =三个大字段>
< Sticky style = {{paddingTop:‘15px’}}>
< SideNav
data = {permissionSections}}
counter = {0}
/>
< / Sticky>
< / div>
< div className =十二个宽字段>
< CheckboxGroup
data = {permissionSections}
counter = {0}
onChange = {this.updateCheckmarks}
/>
< / div>
< / div>
}
< / StickyContainer>
< / div>
);
}
}

我很难理解如何实现类似react的方法-scroll或scrollchor或react-router链接标记,以便能够单击该部分并滚动到页面上的该部分。任何建议都将非常受欢迎。

解决方案

我能够通过以下方式使用浏览器支持的方式:

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

然后将id添加到列表元素。


I have implemented a side menu that has a link tag for each section but I am unsure how to implement the functionality when clicking on them the user is taken to the specific section. I understand how to do it if the it was in the same component and if I was generating the sections in a normal fashion but I am doing it in a different way and I am unsure how to implement something like react-scroll or scrollchor.

Here I am generating the sections with buildTree by mapping over some data I have in another file.

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>
    );
  }
}

I have used the same technique to map over the data to create my sticky sideNav.

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>
    );
  }
}

and this is the parent where they both are rendered.

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>
    );
  }
}

I am having trouble understanding how to implement something like react-scroll or scrollchor or react-router link tags to be able to click on the section and scroll to that section on the page. Any suggestions would be very welcome.

解决方案

I was able to just use the browser supported way by doing:

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

And then just add an id to the list element.

这篇关于点击链接滚动到特定部分react.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆