I'm migrating the code from what I see on here on CodePen.
Within IssueBox
, I am planning to implement a form which an enduser will update setting a state from 'unverified' to 'verified'.
App
(ill rename this component) will be my parent and IssueBox
would be the child.
So I got through flux => Action -> dispatcher -> udpate db -> update view.
Now that I have the new state and the view should be updated, do I use componentWillRecieveProps() and then setState there, so that in IssueBox
I can continue using this.props thus in turn updating it.
import React, { Component } from "react";
import IssueBox from "./issuebox.js";
import "./App.css";
class App extends Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
email: [],
counter: 0,
title: "Test run"
};
}
componentDidMount() {
fetch(
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/311743/dummy-emails.json"
)
.then(res => res.json())
.then(result => {
const emails = result.data;
console.log("resutl state: ", emails);
let id = 0;
for (const email of emails) {
email.id = id++;
email.verified = 'False'
}
this.setState({
isLoaded: true,
emails: emails
});
});
}
render() {
//console.log(this.state.email);
return (
<div className="App">
<div>
<IssueBox emails={this.state.email} />
</div>
</div>
);
}
}
//issuebox.js
import React, { Component } from "react";
class IssueBox extends Component {
constructor(args) {
super(args);
const emails = this.props.emails;
console.log("inner props: ", emails);
let id = 0;
for (const email of emails) {
email.id = id++;
}
this.state = {
selectedEmailId: 0,
currentSection: "inbox",
emails
};
}
//...copy and pase from codepen
setSidebarSection(section) {
let selectedEmailId = this.state.selectedEmailId;
if (section !== this.state.currentSection) {
selectedEmailId = "";
}
this.setState({
currentSection: section,
selectedEmailId
});
}
componentWillReceiveProps(newProps) {
// Assign unique IDs to the emails
this.setState({ emails: newProps.data });
}
render() {
const currentEmail = this.state.emails.find(
x => x.id === this.state.selectedEmailId
);
return (
<div>
<Sidebar
emails={this.props.emails}
setSidebarSection={section => {
this.setSidebarSection(section);
}}
/>
)}
///.....copy and pase from codepen
The error is being caused by this line in componentWillReceiveProps()
:
this.setState({ emails: newProps.data });
The emails are coming in on a property called emails
so that line should be:
this.setState({ emails: newProps.emails });
That being said, componentWillReceiveProps()
gets called more frequently than you might expect. I recommend that you add the id
's to the emails within componentDidMount()
of App
so they come into IssueBox
ready to use. This means that App
is keeping the emails in its state and simply passing them to IssueBox
as props, so you can remove emails
from the state in IssueBox
and just use the emails that come in through the props everywhere within IssueBox
(similar to how the other components use emails
coming in on their props and don't keep them in their own local state).