Next.js如何实现所有页面的Material-ui?
Next.js How to implement Material-ui for all pages?
按照 next.js 存储库中的示例:https://github.com/zeit/next.js/tree/v3-beta/examples/with-material-ui
我可以让 Material-ui 为单个页面工作。而且我不想做 getInitialProps 在每个页面上设置 userAgent 道具。
- 我尝试制作一个可以在我的页面中使用的 HOC。但是 getInitialProps 仅适用于页面。所以我的 MyMui 组件无法获取请求对象。
- 我尝试创建 _document.js 页面,并用我的 MuiThemeProvider 包装主页面。但这给了我一堆错误。
那么我怎样才能得到一个干净的解决方案来为我的所有页面实施 material-ui?
我 运行 遇到了类似的问题,并找到了如下所示的解决方案:
// hocs/default-page.js
export default Page => class DefaultPage extends React.Component {
static getInitialProps(ctx) {
// Ensures material-ui renders the correct css prefixes server-side
let userAgent
if (process.browser) {
userAgent = navigator.userAgent
} else {
userAgent = ctx.req.headers['user-agent']
}
// Check if Page has a `getInitialProps`; if so, call it.
const pageProps = Page.getInitialProps && Page.getInitialProps(ctx);
// Return props.
return { ...pageProps, userAgent }
}
...
render() {
return (
<MuiThemeProvider ...>
<Page/>
</MuiThemeProvider>
);
}
}
// pages/index.js
import defaultPage from '../hocs/default-page';
const Page = () => <h1>Hello World</h1>;
Page.getInitialProps = () => { ... };
export default defaultPage(Page);
// Also works for proper components:
export default defaultPage(class MyPage extends React.Component {
static getInitialProps() {
...
}
render() {
...
}
});
- layout.js
/**
* Created by Counter on 5/30/2017.
*/
import React, {Component} from 'react'
import Head from 'next/head'
import RaisedButton from 'material-ui/RaisedButton'
import Dialog from 'material-ui/Dialog'
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import injectTapEventPlugin from 'react-tap-event-plugin'
import {blue100, blue400, blue700} from 'material-ui/styles/colors';
import AppBar from 'material-ui/AppBar';
import TextField from 'material-ui/TextField';
// Needed for onTouchTap
//
try {
if (typeof window !== 'undefined') {
injectTapEventPlugin()
}
} catch (e) {
// do nothing
}
const styles = {
}
const _muiTheme = getMuiTheme({
palette: {
primary1Color: blue400,
primary2Color: blue700,
primary3Color: blue100,
},
});
class Layout extends Component {
render () {
const { userAgent,children } = this.props
/* https://github.com/callemall/material-ui/issues/3336 */
const muiTheme = getMuiTheme(getMuiTheme({userAgent: userAgent}), _muiTheme)
return (
<MuiThemeProvider muiTheme={muiTheme}>
<div>
<Head>
<meta name="viewport" content="initial-scale=1.0, width=device-width"/>
<link rel='stylesheet' href='/static/css/react-md.light_blue-yellow.min.css'/>
</Head>
{children}
</div>
</MuiThemeProvider>
)
}
}
export default Layout
- index.js
import React, {Component} from 'react'
import RaisedButton from 'material-ui/RaisedButton'
import Dialog from 'material-ui/Dialog'
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import injectTapEventPlugin from 'react-tap-event-plugin'
import {blue100,blue400, blue500, blue700,orange500} from 'material-ui/styles/colors';
import Layout from '../component/layout'
import AppBar from 'material-ui/AppBar';
import TextField from 'material-ui/TextField';
import {Tabs, Tab} from 'material-ui/Tabs';
// Needed for onTouchTap
//
try {
if (typeof window !== 'undefined') {
injectTapEventPlugin()
}
} catch (e) {
// do nothing
}
const styles = {
headline: {
fontSize: 24,
paddingTop: 16,
marginBottom: 12,
fontWeight: 400,
},
contentContainerStyle:{
width:300,
marginTop:133,
float:'left'
},
floatingLabelStyle: {
color: orange500,
},
floatingLabelFocusStyle: {
color: blue500,
},
tabDiv:{
textAlign:'center',
backgroundColor: 'rgb(242, 244, 255);',
boxShadow: '10px 10px 5px #888888',
minHeight:350
},
button: {
margin: 12,
},
descDiv:{
width: '413px',
float: 'left',
margin: '133px 450px 0 25px',
},
outerDiv:{
display:'inline-block'
}
};
const _muiTheme = getMuiTheme({
palette: {
primary1Color: blue400,
primary2Color: blue700,
primary3Color: blue100,
},
});
class Main extends Component {
static getInitialProps ({ req }) {
const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
const isServer = !!req
return {isServer, userAgent}
}
constructor (props, context) {
super(props, context);
this.state = {
clicked: false
}
}
render () {
const { userAgent } = this.props;
return(
<Layout userAgent={userAgent} >
<div style={styles.outerDiv}>
<div style={styles.descDiv}>
<p>Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the
industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and
scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap
into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the
release of Letraset sheets containing Lorem </p>
<RaisedButton
target="_blank"
label="Test Your Api"
primary={true}
style={styles.button}
icon=''
/>
</div>
<Tabs
value={this.state.value}
onChange={this.handleChange}
style={styles.contentContainerStyle}
>
<Tab label="Login" value="a">
<div style={styles.tabDiv}>
<TextField
floatingLabelText="Username"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<TextField
floatingLabelText="Password"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<br/>
<RaisedButton
target="_blank"
label="Submit"
secondary={true}
style={styles.button}
icon=''
/>
</div>
</Tab>
<Tab label="SignUp" value="b">
<div style={styles.tabDiv}>
<TextField
floatingLabelText="Username"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<TextField
floatingLabelText="Password"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<TextField
floatingLabelText="Confirm Password"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<br/>
<RaisedButton
target="_blank"
label="Submit"
secondary={true}
style={styles.button}
icon=''
/>
</div>
</Tab>
</Tabs>
</div>
</Layout>
)
}
}
export default Main
- 以上文件来自我的项目。我创建了 layout.js 文件,我在所有页面中都使用了该文件。这是一种方法。
按照 next.js 存储库中的示例:https://github.com/zeit/next.js/tree/v3-beta/examples/with-material-ui
我可以让 Material-ui 为单个页面工作。而且我不想做 getInitialProps 在每个页面上设置 userAgent 道具。
- 我尝试制作一个可以在我的页面中使用的 HOC。但是 getInitialProps 仅适用于页面。所以我的 MyMui 组件无法获取请求对象。
- 我尝试创建 _document.js 页面,并用我的 MuiThemeProvider 包装主页面。但这给了我一堆错误。
那么我怎样才能得到一个干净的解决方案来为我的所有页面实施 material-ui?
我 运行 遇到了类似的问题,并找到了如下所示的解决方案:
// hocs/default-page.js
export default Page => class DefaultPage extends React.Component {
static getInitialProps(ctx) {
// Ensures material-ui renders the correct css prefixes server-side
let userAgent
if (process.browser) {
userAgent = navigator.userAgent
} else {
userAgent = ctx.req.headers['user-agent']
}
// Check if Page has a `getInitialProps`; if so, call it.
const pageProps = Page.getInitialProps && Page.getInitialProps(ctx);
// Return props.
return { ...pageProps, userAgent }
}
...
render() {
return (
<MuiThemeProvider ...>
<Page/>
</MuiThemeProvider>
);
}
}
// pages/index.js
import defaultPage from '../hocs/default-page';
const Page = () => <h1>Hello World</h1>;
Page.getInitialProps = () => { ... };
export default defaultPage(Page);
// Also works for proper components:
export default defaultPage(class MyPage extends React.Component {
static getInitialProps() {
...
}
render() {
...
}
});
- layout.js
/**
* Created by Counter on 5/30/2017.
*/
import React, {Component} from 'react'
import Head from 'next/head'
import RaisedButton from 'material-ui/RaisedButton'
import Dialog from 'material-ui/Dialog'
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import injectTapEventPlugin from 'react-tap-event-plugin'
import {blue100, blue400, blue700} from 'material-ui/styles/colors';
import AppBar from 'material-ui/AppBar';
import TextField from 'material-ui/TextField';
// Needed for onTouchTap
//
try {
if (typeof window !== 'undefined') {
injectTapEventPlugin()
}
} catch (e) {
// do nothing
}
const styles = {
}
const _muiTheme = getMuiTheme({
palette: {
primary1Color: blue400,
primary2Color: blue700,
primary3Color: blue100,
},
});
class Layout extends Component {
render () {
const { userAgent,children } = this.props
/* https://github.com/callemall/material-ui/issues/3336 */
const muiTheme = getMuiTheme(getMuiTheme({userAgent: userAgent}), _muiTheme)
return (
<MuiThemeProvider muiTheme={muiTheme}>
<div>
<Head>
<meta name="viewport" content="initial-scale=1.0, width=device-width"/>
<link rel='stylesheet' href='/static/css/react-md.light_blue-yellow.min.css'/>
</Head>
{children}
</div>
</MuiThemeProvider>
)
}
}
export default Layout
- index.js
import React, {Component} from 'react'
import RaisedButton from 'material-ui/RaisedButton'
import Dialog from 'material-ui/Dialog'
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import injectTapEventPlugin from 'react-tap-event-plugin'
import {blue100,blue400, blue500, blue700,orange500} from 'material-ui/styles/colors';
import Layout from '../component/layout'
import AppBar from 'material-ui/AppBar';
import TextField from 'material-ui/TextField';
import {Tabs, Tab} from 'material-ui/Tabs';
// Needed for onTouchTap
//
try {
if (typeof window !== 'undefined') {
injectTapEventPlugin()
}
} catch (e) {
// do nothing
}
const styles = {
headline: {
fontSize: 24,
paddingTop: 16,
marginBottom: 12,
fontWeight: 400,
},
contentContainerStyle:{
width:300,
marginTop:133,
float:'left'
},
floatingLabelStyle: {
color: orange500,
},
floatingLabelFocusStyle: {
color: blue500,
},
tabDiv:{
textAlign:'center',
backgroundColor: 'rgb(242, 244, 255);',
boxShadow: '10px 10px 5px #888888',
minHeight:350
},
button: {
margin: 12,
},
descDiv:{
width: '413px',
float: 'left',
margin: '133px 450px 0 25px',
},
outerDiv:{
display:'inline-block'
}
};
const _muiTheme = getMuiTheme({
palette: {
primary1Color: blue400,
primary2Color: blue700,
primary3Color: blue100,
},
});
class Main extends Component {
static getInitialProps ({ req }) {
const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
const isServer = !!req
return {isServer, userAgent}
}
constructor (props, context) {
super(props, context);
this.state = {
clicked: false
}
}
render () {
const { userAgent } = this.props;
return(
<Layout userAgent={userAgent} >
<div style={styles.outerDiv}>
<div style={styles.descDiv}>
<p>Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the
industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and
scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap
into electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s with the
release of Letraset sheets containing Lorem </p>
<RaisedButton
target="_blank"
label="Test Your Api"
primary={true}
style={styles.button}
icon=''
/>
</div>
<Tabs
value={this.state.value}
onChange={this.handleChange}
style={styles.contentContainerStyle}
>
<Tab label="Login" value="a">
<div style={styles.tabDiv}>
<TextField
floatingLabelText="Username"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<TextField
floatingLabelText="Password"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<br/>
<RaisedButton
target="_blank"
label="Submit"
secondary={true}
style={styles.button}
icon=''
/>
</div>
</Tab>
<Tab label="SignUp" value="b">
<div style={styles.tabDiv}>
<TextField
floatingLabelText="Username"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<TextField
floatingLabelText="Password"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<TextField
floatingLabelText="Confirm Password"
floatingLabelStyle={styles.floatingLabelStyle}
floatingLabelFocusStyle={styles.floatingLabelFocusStyle}
/>
<br/>
<RaisedButton
target="_blank"
label="Submit"
secondary={true}
style={styles.button}
icon=''
/>
</div>
</Tab>
</Tabs>
</div>
</Layout>
)
}
}
export default Main
- 以上文件来自我的项目。我创建了 layout.js 文件,我在所有页面中都使用了该文件。这是一种方法。