最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Reactjs way of hide sidebar in layout? - Stack Overflow

programmeradmin0浏览0评论

I am wondering how I can handle these 2 layouts.

First I have a css grid layout that gets used on resolutions of 1024px or bigger and if they support current grid standard.

Pretty standard layout with a header, sidebar and main area.

.container {
  display: grid;
  grid-template-columns: 0.30fr 0.70fr;
  grid-template-rows: auto;
  grid-template-areas: "header header" "sidebar main";
}

.header {
  grid-area: header;
  background-color: yellow;
}

.sidebar {
  grid-area: sidebar;
  background-color: lightblue;
}

.main {
  grid-area: main;
  background-color: green;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <div class="container">
    <div class="header">
      header
    </div>
    <div class="sidebar">
      side
    </div>
    <div class="main">
      main
    </div>
  </div>
</body>

</html>

I am wondering how I can handle these 2 layouts.

First I have a css grid layout that gets used on resolutions of 1024px or bigger and if they support current grid standard.

Pretty standard layout with a header, sidebar and main area.

.container {
  display: grid;
  grid-template-columns: 0.30fr 0.70fr;
  grid-template-rows: auto;
  grid-template-areas: "header header" "sidebar main";
}

.header {
  grid-area: header;
  background-color: yellow;
}

.sidebar {
  grid-area: sidebar;
  background-color: lightblue;
}

.main {
  grid-area: main;
  background-color: green;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <div class="container">
    <div class="header">
      header
    </div>
    <div class="sidebar">
      side
    </div>
    <div class="main">
      main
    </div>
  </div>
</body>

</html>

Now if the browser does not support grid or they are below 1024px then they go to the mobile layout.

This layout would be made by flex and bees a layout of header and main area with the sidebar being hidden and only shown by user interaction.

I just can't figure out a react way of doing this that I am happy with.

My problem is that I can hide the side menu with media selectors and then on click of the hamburger menu toggle the display but I don't know if this feels like a reactjs way of doing it as I rather just not render the side bar instead of hiding it.

I would also have to have something to handle window on resize.

Share Improve this question asked Nov 19, 2017 at 18:44 chobo2chobo2 86k207 gold badges552 silver badges862 bronze badges 3
  • it's perfectly valid to use media selectors. it doesn't go against the react paradigm if it's simply a mobile layout change :) – Max Sindwani Commented Nov 19, 2017 at 18:47
  • Well, I would still need to do some react on the sidebar as I want the user to be able to toggle the sidebar basically whenever they like on the mobile layout. So I would probably have to add a class to it via the state. Like I said I just like having things not rendered vs just hidden. – chobo2 Commented Nov 19, 2017 at 18:53
  • Well then yes, deciding to not render it is up to you. From my experience it makes it easier to apply transitions when you hide it rather than not rendering it altogether. Also using JS for resize events tends to be a bit more messy and plicated than using media selectors (especially if you trigger a react update on resize). My remendation would be to use both media selectors and a class for toggling the sidebar – Max Sindwani Commented Nov 19, 2017 at 19:05
Add a ment  | 

1 Answer 1

Reset to default 2

If you really want to do this only in reactjs way you can do this using life cycle methods like ponentWillMount, ponentDidMount and ponentWillUnmount along with resize event and document's width.

I did not do much work the CSS part in this example, but you will get the idea.

Try resizing the window after running this script in full-page view.

class MyLayout extends React.Component {
    constructor() {
      super();
      this.state = {
        mobileView: false,
        showSidebar: true
      };
      this.updateViewState = this.updateViewState.bind(this);
      this.toggleSideBar = this.toggleSideBar.bind(this);
    }
    updateViewState() {
      if (!this.state.mobileView && document.documentElement.clientWidth < 1024) {
        this.setState({
          mobileView: true,
          showSidebar: false
        });
      } else if (document.documentElement.clientWidth > 1024) {
        this.setState({
          mobileView: false,
          showSidebar: true
        });
      }
    }
    toggleSideBar() {
      this.setState({
        showSidebar: !this.state.showSidebar
      });
    }
    ponentWillMount() {
      this.updateViewState();
    }
    ponentDidMount() {
      window.addEventListener("resize", this.updateViewState);
    }
    ponentWillUnmount() {
      window.removeEventListener("resize", this.updateViewState);
    }
    render() {
      let containerClass = 'container';
      if (this.state.mobileView) containerClass = containerClass + ' mobileview';
      return (
        <div className = { containerClass }>
          <div className="header"> {this.state.mobileView && <button onClick={this.toggleSideBar} />} header 
          </div> 
        {
          this.state.showSidebar &&
          <div className = "sidebar" >
            side 
          </div>
        } 
        <div className="main">
          main 
        </div> 
      </div>);
    }
 }

ReactDOM.render( 
  <MyLayout /> ,
  document.getElementById('container')
);
.container {
  display: grid;
  grid-template-columns: 0.30fr 0.70fr;
  grid-template-rows: auto;
  grid-template-areas: "header header" "sidebar main";
}

.mobileview {
  grid-template-columns: 0fr 1fr;
}

.mobileview.sidebar {
  float: left;
}

.header {
  grid-area: header;
  background-color: yellow;
}

.sidebar {
  grid-area: sidebar;
  background-color: lightblue;
}

.main {
  grid-area: main;
  background-color: green;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
  <!-- This element's contents will be replaced with your ponent. -->
</div>

发布评论

评论列表(0)

  1. 暂无评论