【问题标题】:How to switch multiple react components on same page如何在同一页面上切换多个反应组件
【发布时间】:2018-05-21 02:01:16
【问题描述】:

我有一个使用 material-ui 列表构建的用户仪表板。对于每个 listItem 我都有一个组件。我想要的是,当我单击列表元素时,有一个专门用于切换组件的部分。我无法实现这一点。这是我的代码。我不确定将onClick 处理程序放在哪里。我会很感激任何线索。甚至在单击特定 listItem 时登录。然后我可以继续使用反应条件渲染。 在下图中,当用户单击所有事件时,右侧会呈现一个组件。当MyEvents 被点击时,它的一个组件就会被渲染出来。

代码:

UserTileData.js

export const profileFolderListItems = (
  <div>
    <ListItem button>
     <ListItemIcon>
       <SendIcon />
     </ListItemIcon>
     <Badge badgeContent={3} color='primary'>
       <ListItemText primary='Events attending' />
     </Badge>
     </ListItem>
     <ListItem button>
       <ListItemIcon>
        <CreateIcon />
       </ListItemIcon>
     <ListItemText primary='New Event' />
    </ListItem>

  </div>
)

UserProfilePage.js

 class UserProfile extends Component {
  constructor (props) {
    super(props)
    this.state = {
      componentTodisplay: null

    }
  }

  render () {
    const { classes } = this.props

    return (
      <div>

        <div className={classes.root}>

          <Drawer
            variant='permanent'
            classes={{
              paper: classes.drawerPaper
            }}
          >
            <div className={classes.toolbar} />
            <List >{eventsFolderListItems}</List>
            <Divider />
            <List>{profileFolderListItems}</List>
          </Drawer>
          <main className={classes.content}>
            <div className={classes.toolbar} />
            {/* componentToDisplay goes here */}

          </main>
        </div>
      </div>
    )
  }
}

UserProfile.propTypes = {
  classes: PropTypes.object.isRequired
}

export default withStyles(styles)(UserProfile)

【问题讨论】:

  • 您能否澄清一下切换组件的实际含义?你想条件渲染吗?还是换道具?
  • @Abrar 我已经用视觉辅助更新了这个问题
  • 您如何传递profileFolderListItems 中的列表项名称?我的意思是primary props,不应该是动态渲染的吗?
  • UserTileData.js 有这些信息。

标签: reactjs material-ui


【解决方案1】:

您应该使用 React Router(或任何类似的路由库)。

https://github.com/ReactTraining/react-router

https://reacttraining.com/react-router/web/example/basic

在下图中,当用户点击所有事件时,一个组件用于 即在右侧呈现。单击 MyEvents 时,一个组件 为它,被渲染。

如果用户可以浏览到/my-events/all-events,或者将它们添加为书签,这也可能会有所帮助。当用户在浏览器中按下后退/前进按钮时会怎样?

使用路由库可以解决所有这些问题(以及更多问题!)你。

【讨论】:

  • 谢谢。在用户体验和导航方面,我没有想到这一点。此外,我在您提供的链接之一中看到了类似于我想要的内容。大开眼界@thirtydot
【解决方案2】:

为您的代码添加了一些更改。现在看起来像这样 -

UserTileData.js

export class profileFolderListItems {
  constructor(props){
    super(props);
  }

  render() {
    return (
      <div>
        <ListItem button>
         <ListItemIcon>
           <SendIcon />
         </ListItemIcon>
         <Badge badgeContent={3} color='primary'>
           {/* notice the onClick handler here */}
           <ListItemText primary='Events attending' onClick={() => this.props.onSelectChange('events')}
         </Badge>
         </ListItem>
         <ListItem button>
           <ListItemIcon>
            <CreateIcon />
           </ListItemIcon>
         <ListItemText primary='New Event' />
        </ListItem>
      </div>
    )
  }
}

UserProfile.js

import { profileFolderListItems, eventsFolderListItems} from './UserTitleData';

class UserProfile extends Component {
  constructor (props) {
    super(props)
    this.state = {
      value: null
    };

    this.handleSelectOption = this.handleSelectOption.bind(this);
  }

  handleSelectOption(value) {
    this.setState({
        value: value
    });
  }

  render () {
    const { classes } = this.props;

    return (
      <div>

        <div className={classes.root}>
          <Drawer
            variant='permanent'
            classes={{
              paper: classes.drawerPaper
            }}
          >
            <div className={classes.toolbar} />

          </Drawer>
          <main className={classes.content}>
            <div className={classes.toolbar} />
            {/* notice the conditional rendering here */}

            {this.state.value === 'events' ?
              (<List>
                <profileFolderListItems
                  onSelectChange={this.handleSelectOption}
                />
                </List>) : 
             this.state.value === 'profile' ?
               (
                 <List>
                   <profileFolderListItems
                     onSelectChange={this.handleSelectOption}
                   />
                 </List>
               ) : null}

          </main>
        </div>
      </div>
    )
  }

基本上我在这里做的是-

  • ListItemText 中的值传递给onClick 处理程序。 (每个选项都应该是唯一的。我只在这里传递events
  • 将值提升到父组件 - UserProfilePage。 (React 的单一事实来源,除非你使用 Redux)

  • 根据传递的值进行条件渲染。

希望你明白了。

【讨论】:

  • 非常感谢。我会看看它然后让你知道。是的,我明白了。
  • 成功了。再次感谢。一个后续问题,为什么我们这样使用空括号? {() =&gt; this.props.onSelectChange('events')}
  • 很高兴知道这一点!我使用了 ES6 的箭头函数,第一个括号是空的,因为我没有传递任何值作为参数。如果你想传递一个值,你应该在第一个括号中传递它
猜你喜欢
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 2020-01-09
  • 2017-08-11
相关资源
最近更新 更多