I'm trying to work out how I would render a component differently in mobile view (I would like it to appear before my header in mobile, but after otherwise)
The code I have at the minute is
import React from 'react';
import NavigationBar from './NavigationBar';
import SiteHeader from './SiteHeader';
export default class App extends Component {
constructor(props) {
super(props);
let width = window.innerWidth;
if (width > 768) {
this.setState(renderComponent =
`<div className="container">
<NavigationBar />
<SiteHeader />
{this.props.children}
</div>`
);
} else {
this.setState(renderComponent =
`<div className="container">
<NavigationBar />
<SiteHeader />
{this.props.children}
</div>`
);
}
}
render() {
return (
{renderComponent}
);
}
}
However this is not working (Component is not defined), I figured I couldn't just set the component as strings but hopefully this is enough info for any suggestions on the correct way to do it
Thanks!
Your code has several issues, see comments for more details:
export default class App extends Component {
constructor(props) {
super(props);
// typo: use `=` instead of `:`
let width = window.innerWidth;
// dont use setState in constructor, initialize state instead
this.state = {};
if (width > 768) {
// set renderComponent property according to window size
// components are declared using JSX, not string (do not use ``)
this.state.renderComponent = (
<div className="container">
<NavigationBar />
<SiteHeader />
{this.props.children}
</div>
);
} else {
this.state.renderComponent = (
<div className="container">
<NavigationBar />
<SiteHeader />
{this.props.children}
</div>
);
}
}
render() {
// access state through `this.state`
// you don't need {} while it is not inside JSX
return this.state.renderComponent;
}
}
Furthermore I would move this logic to the render method, don't use state to store components but render it directly. For example:
export default class App extends Component {
render() {
let width = window.innerWidth;
if (width > 768) {
return (
<div className="container">
<NavigationBar />
<SiteHeader />
{this.props.children}
</div>
);
} else {
return (
<div className="container">
<NavigationBar />
<SiteHeader />
{this.props.children}
</div>
);
}
}
}
I think you should have your rendering logic in render()
method. You could use matchMedia()
to render components differently based on resolution or orientation - similarly as when using media queries.
https://developer.mozilla.org/pl/docs/Web/API/Window/matchMedia
You can try this:
componentWillMount = () => {
let mql = window.matchMedia("all and (max-width: 767px)")
if (mql.matches) { // if media query matches
document.body.style.backgroundColor = "#fff";
} else {
document.body.style.backgroundColor = "#2d74da";
}
}
componentWillUnmount = () => {
document.body.style.backgroundColor = null;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.