Hello and thank you for your time:
I am following the following tutorial:https://app.pluralsight.com/library/courses/react-flux-building-applications/table-of-contents
And currently I have detected that when you try to create an author, it tries to load current's author's URL's author id. Because of it is being created, it is undefined, and so then the create author functionality does not work.
I have read some topics about checking undefined type both in JS and React: How to determine if variable is 'undefined' or 'null'?
Checking for Undefined In React
https://github.com/facebook/react/issues/3725
And I have tried the following:
In manageAuthorForm we pass in to the authorForm the author's state:
render() {
return (
<AuthorForm author={this.state.author}
onChange={this.setAuthorState}
onSave={this.saveAuthor}/>
);
};
And then I have tried into the AuthorForm:
import React from 'react';
import {Input} from "../common/textInput";
import Link from "react-router-dom/es/Link";
class AuthorForm extends React.Component {
componentWillReceiveProps(nextProps) {
if (nextProps.state.author === undefined) {
this.props.author = {
author: {
id: '',
firstName: '',
lastName: '',
}
};
}
}
render() {
return (
<form>
<h1>Manage author</h1>
<Input
name="firstName"
label="First Name"
value={this.props.author.firstName}
onChange={this.props.onChange}
/>
<Input
name="lastName"
label="Last Name"
value={this.props.author.lastName}
onChange={this.props.onChange}
/>
<button type="submit" value="Save" className="btn btn-default" onClick={this.props.onSave}><Link
to="/authors">Save
author</Link>
</button>
</form>
);
}
}
export {AuthorForm}
And it reports that nextProps are undefined:
Uncaught TypeError: Cannot read property 'author' of undefined
at AuthorForm.componentWillReceiveProps (authorForm.js:7)
at callComponentWillReceiveProps (react-dom.development.js:6389)
at updateClassInstance (react-dom.development.js:6575)
at updateClassComponent (react-dom.development.js:7848)
at beginWork (react-dom.development.js:8225)
at performUnitOfWork (react-dom.development.js:10224)
at workLoop (react-dom.development.js:10288)
at HTMLUnknownElement.callCallback (react-dom.development.js:542)
at Object.invokeGuardedCallbackDev (react-dom.development.js:581)
at invokeGuardedCallback (react-dom.development.js:438)
at renderRoot (react-dom.development.js:10366)
at performWorkOnRoot (react-dom.development.js:11014)
at performWork (react-dom.development.js:10967)
at requestWork (react-dom.development.js:10878)
at scheduleWorkImpl (react-dom.development.js:10732)
at scheduleWork (react-dom.development.js:10689)
at scheduleTopLevelUpdate (react-dom.development.js:11193)
at Object.updateContainer (react-dom.development.js:11231)
at react-dom.development.js:15226
at Object.unbatchedUpdates (react-dom.development.js:11102)
at renderSubtreeIntoContainer (react-dom.development.js:15225)
at Object.render (react-dom.development.js:15290)
at Object../src/index.js (index.js:17)
at __webpack_require__ (bootstrap 78b34f0f34b98a41c613:678)
at fn (bootstrap 78b34f0f34b98a41c613:88)
at Object.0 (authorStore.js:39)
at __webpack_require__ (bootstrap 78b34f0f34b98a41c613:678)
at bootstrap 78b34f0f34b98a41c613:724
at bootstrap 78b34f0f34b98a41c613:724
componentWillReceiveProps @ authorForm.js:7
callComponentWillReceiveProps @ react-dom.development.js:6389
updateClassInstance @ react-dom.development.js:6575
updateClassComponent @ react-dom.development.js:7848
beginWork @ react-dom.development.js:8225
performUnitOfWork @ react-dom.development.js:10224
workLoop @ react-dom.development.js:10288
callCallback @ react-dom.development.js:542
invokeGuardedCallbackDev @ react-dom.development.js:581
invokeGuardedCallback @ react-dom.development.js:438
renderRoot @ react-dom.development.js:10366
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
requestWork @ react-dom.development.js:10878
scheduleWorkImpl @ react-dom.development.js:10732
scheduleWork @ react-dom.development.js:10689
scheduleTopLevelUpdate @ react-dom.development.js:11193
updateContainer @ react-dom.development.js:11231
(anonymous) @ react-dom.development.js:15226
unbatchedUpdates @ react-dom.development.js:11102
renderSubtreeIntoContainer @ react-dom.development.js:15225
render @ react-dom.development.js:15290
./src/index.js @ index.js:17
__webpack_require__ @ bootstrap 78b34f0f34b98a41c613:678
fn @ bootstrap 78b34f0f34b98a41c613:88
0 @ authorStore.js:39
__webpack_require__ @ bootstrap 78b34f0f34b98a41c613:678
(anonymous) @ bootstrap 78b34f0f34b98a41c613:724
(anonymous) @ bootstrap 78b34f0f34b98a41c613:724
And in the web browser it reports:
×
TypeError: Cannot read property 'author' of undefined
AuthorForm.componentWillReceiveProps
C:/Users/YonePC/WebstormProjects/flux/src/components/authors/authorForm.js:7
4 |
5 | class AuthorForm extends React.Component {
6 | componentWillReceiveProps(nextProps) {
> 7 | if (nextProps.state.author === undefined) {
8 | this.props.author = {
9 | author: {
10 | id: '',
View compiled
▶ 15 stack frames were collapsed.
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.
The full code, in github: https://github.com/YoneMoreno/ReactFluxAuthorsPageTutorial
Could you help me, please?
Thank you ;=)
Simple solution will be:
<AuthorForm
author={this.state.author || {firstName:'', lastName:'', id:''}}
...
/>
And remove the componentWillReceiveProps
method from child component.
Better approach will be:
1- Either assign the initial value of author
in state as:
this.state = {
author: {firstName:'', lastName:'', id:''}
}
2- Or inside render method of child component, write it like this:
render(){
const {firstName='', lastName='', id=''} = this.props.author || {};
return(....)
}
And use firstName, lastName, id
directly instead of this.props.
Issues in your code:
1- It should be nextProps.author
instead of nextProps.state.author
in componentWillReceiveProps
lifecycle method.
2- Props are read-only, Whether you declare a component as a function or a class, it must never modify its own props. You are trying to change the value in componentWillReceiveProps
.
Your error message is;
Cannot read property 'author' of undefined
It is actually not author
that is undefined but nextProps.state
. nextProps
is an object containing the contents of only the props.
The other problem here is that componentWillReceiveProps()
is not called when when mounting, thus if props.author
is initially undefined then that error handling won't work. Mayank Shukla has a good answer, however that requires you to have a constructor like so;
constructor(props) {
super(props);
this.state = {
author: this.props.author,
};
}
Since props cannot be updated, it makes more sense to put it in the state so that it can be in the future. If you need to receive prop updates, use setState()
in componentWillUpdate()
Another, more long winded solution would be to make author
a required prop, and not attempt to create that component until the necessary props exist. This is also better practice.
AuthorForm.propTypes = {
author: PropTypes.string.isRequired,
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With