基于具有缓存的所选菜单来更改内容更改

时间:2016-10-06 08:27:42

标签: reactjs react-redux

我有这段代码。



class Component {
  
  state = {
    selectedView: 'foo',
  }
  
  onMenuClicked(event, menuItem) {
    switch(menuItem) {
      case 'foo':
        this.setState({ selectedView: 'foo'})
        break;
      case 'bar':
        this.setState({ selectedView: 'bar'})
        break;
    }
  }
  
  renderBar() {
    return <Bar />    
  }

  renderFoo() {
    return <Foo />  
  }
  
  renderContent() {
    switch(this.state.selectedView) {
      case 'foo':
        return this.renderFoo();
      case 'bar':
        return this.renderBar();
    }
  }
  
  render() {
    return(
      <div>
        <Menu onMenuSelected((e, menuItem) => this.onMenuClicked(e, menyItem)) /> // items foo and bar
        {this.renderContent()}
      </div>
    )
  }
&#13;
&#13;
&#13;

这很好用。但是,由于foo和bar组件非常重,并且用户在这些组件之间切换的可能性很高,我想有这样的流程,

  • 在页面加载时,渲染foo
  • 如果是第一次点击栏,则渲染栏
  • 对于所有后续菜单更改,只需隐藏/显示foo / bar组件(基于单击的菜单),并且不会在每次菜单更改时重新加载它们。

我需要调整我的代码(尽可能最干净的方式)才能有这样的行为。任何帮助,将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

处理此问题的一种方法是在元素上使用display: none并跟踪已显示的元素。这种方式react将始终将呈现的组件保留在DOM中,并且仅更新display值。

class Component {

  state = {
    selectedView: 'foo',
    foo: true // to indicate that foo has been rendered
  }

  onMenuClicked(event, menuItem) {
    switch(menuItem) {
      case 'foo':
        this.setState({ selectedView: 'foo', foo: true})
        break;
      case 'bar':
        this.setState({ selectedView: 'bar', bar: true})
        break;
    }
  }

  renderBar() {
    const selected = this.state.selectedView === 'bar';

    if (!this.state.bar) {
        return <div/> // don't render bar at all
    }
    return <div style={{display: selected ? 'block' : 'none'}}>
        <Bar />
    </div>
  }

  renderFoo() {
    const selected = this.state.selectedView === 'foo';

    if (!this.state.foo) {
        return <div/> // don't render foo at all
    }
    return <div style={{display: selected ? 'block' : 'none'}}>
        <Foo/>
    </div>
  }

  renderContent() {
    return <div>
        {this.renderFoo()}
        {this.renderBar()}
    <div/>
  }

  render() {
    return(
      <div>
        <Menu onMenuSelected((e, menuItem) => this.onMenuClicked(e, menyItem)) /> // items foo and bar
        {this.renderContent()}
      </div>
    )
  }