1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Throw error if getInitialProps is defined as as instance method (#4922)

* Throw error if getInitialProps is defined as as instance method

Omitting the static keyword happens pretty often. Therefore we should trigger a warning in devmode.

Closes: #4782

* Document getInitialProps error

* Add unit tests for loadGetInitialProps
This commit is contained in:
HaNdTriX 2018-08-09 19:13:44 +02:00 committed by Tim Neutkens
parent 136585e296
commit d1b67623f6
3 changed files with 99 additions and 0 deletions

View file

@ -0,0 +1,39 @@
# getInitialProps was defined as an instance method
#### Why This Error Occurred
`getInitialProps` must be a static method in order to be called by next.js.
#### Possible Ways to Fix It
Use the static keyword.
```js
export default class YourEntryComponent extends React.Component {
static getInitialProps () {
return {}
}
render () {
return 'foo'
}
}
```
or
```js
const YourEntryComponent = function () {
return 'foo'
}
YourEntryComponent.getInitialProps = () => {
return {}
}
export default YourEntryComponent
```
### Useful Links
- [Fetching data and component lifecycle](https://github.com/zeit/next.js#fetching-data-and-component-lifecycle)

View file

@ -54,6 +54,14 @@ export function isResSent (res) {
}
export async function loadGetInitialProps (Component, ctx) {
if (process.env.NODE_ENV !== 'production') {
if (Component.prototype && Component.prototype.getInitialProps) {
const compName = getDisplayName(Component)
const message = `"${compName}.getInitialProps()" is defined as an instance method - visit https://err.sh/next.js/get-inital-props-as-an-instance-method for more information.`
throw new Error(message)
}
}
if (!Component.getInitialProps) return {}
const props = await Component.getInitialProps(ctx)

View file

@ -0,0 +1,52 @@
/* global describe, it, expect */
import { loadGetInitialProps } from '../../dist/lib/utils'
describe('loadGetInitialProps', () => {
it('should throw if getInitialProps is defined as an instance method', () => {
class TestComponent {
getInitialProps () {}
}
const rejectPromise = loadGetInitialProps(TestComponent, {})
const error = new Error('"TestComponent.getInitialProps()" is defined as an instance method - visit https://err.sh/next.js/get-inital-props-as-an-instance-method for more information.')
return expect(rejectPromise).rejects.toEqual(error)
})
it('should resolve to an object if getInitialProps is missing', async () => {
const result = await loadGetInitialProps(() => {}, {})
expect(result).toEqual({})
})
it('should resolve getInitialProps', async () => {
class TestComponent {
static async getInitialProps () {
return { foo: 1 }
}
}
const result = await loadGetInitialProps(TestComponent, {})
expect(result).toEqual({ foo: 1 })
})
it('should be able to return an invalid value if the request was already sent', async () => {
class TestComponent {
static async getInitialProps () {
return 'invalidValue'
}
}
const ctx = {
res: {
finished: true
}
}
const result = await loadGetInitialProps(TestComponent, ctx)
expect(result).toBe('invalidValue')
})
it('should throw if getInitialProps won\'t return an object ', () => {
class TestComponent {
static async getInitialProps () {}
}
const rejectPromise = loadGetInitialProps(TestComponent, {})
const error = new Error('"TestComponent.getInitialProps()" should resolve to an object. But found "undefined" instead.')
return expect(rejectPromise).rejects.toEqual(error)
})
})