I have a button in a child component for debugging purposes that prints the current state in its parent component. When it prints, that is how I want the state to be. When I hit another button in the same child component, the state changes in the parent, by removing a few properties.
Notice how the Id
and SEO_CSEO_Survey_Questions__r
properties are now missing.
Child Component
import React, { Component } from 'react';
import { Link } from 'react-router';
class Index extends Component {
constructor(props){
super(props)
this.state = {
selected: 'created'
}
this.updatePreview = this.updatePreview.bind(this);
this.renderEditArea = this.renderEditArea.bind(this);
}
isActive(value) {
return 'slds-tabs--default__item '+((value===this.state.selected) ?'slds-active':'');
}
updatePreview(e){
const updatedPreview = {
...this.props.selectedPreview,
[e.target.name]: e.target.value
};
this.props.update(updatedPreview)
}
// determines which type of edit area should display
// survey settings or question
renderEditArea() {
let selected = this.props.selectedPreview;
let hasNameKey = "Name" in selected;
if(hasNameKey){
return (
<div>
<input
onChange={(e) => this.updatePreview(e)}
name="Name"
type="text"
className="slds-input"
value={selected.Name ? selected.Name : ''}
/>
<input
onChange={(e) => this.updatePreview(e)}
name="SEO__Welcome_Text__c"
type="text"
className="slds-input"
value={selected.SEO__Welcome_Text__c ? selected.SEO__Welcome_Text__c : ''}
/>
</div>
)
}else {
return (
<input
onChange={(e) => this.updatePreview(e)}
name="SEO__Question__c"
type="text"
className="slds-input"
value={selected.SEO__Question__c ? selected.SEO__Question__c : ''}
/>
)
}
}
render() {
return (
<div className="slds-size--1-of-1 slds-medium-size--4-of-5 slds-large-size--4-of-5">
<div className="slds-tabs--default">
<h2 className="slds-text-heading--small slds-p-top--x-small" style={{position: "absolute"}}>
<button onClick={this.props.addQuestion} className="slds-button slds-button--icon slds-p-left--xx-small" title="add sur">
<svg className="slds-button__icon slds-button__icon--medium" aria-hidden="true">
<use xlinkHref={addIcon}></use>
</svg>
<span className="slds-assistive-text">Add Question</span>
</button>
</h2>
<ul className="slds-tabs--default__nav" style={{justifyContent: "flex-end"}}>
<Link to="/"className="slds-button slds-button--neutral">Back</Link>
<button onClick={this.props.save} className="slds-button slds-button--brand">Save</button>
<button onClick={this.props.currentState} className="slds-button slds-button--brand">Current State</button>
</ul>
</div>
<div className="slds-grid slds-wrap slds-grid--pull-padded">
{this.renderEditArea()}
</div>
</div>
);
}
}
export default Index;
Parent
import React, { Component } from 'react';
import { getQuestions, addQuestion, deleteQuestion, newSurveyQuestions, updateSurveyQuestions, EMPTY_SURVEY } from './helpers';
import SideBar from './survey/SideBar';
import MainArea from './survey/Index';
class Survey extends Component {
constructor(props) {
super(props)
this.state = {
survey: [],
selectedPreview: []
}
this.componentWillMount = this.componentWillMount.bind(this);
this.save = this.save.bind(this);
this.setSelectedPreview = this.setSelectedPreview.bind(this);
this.currentState = this.currentState.bind(this);
}
// if the url is `/survey/new`, create an empty survey
// to save for later.
// else if there is an id in the url, load the survey and questions
componentWillMount(){
if(this.props.pathname === "/survey/new") {
this.setState({
survey: EMPTY_SURVEY,
selectedPreview: EMPTY_SURVEY[0]
})
} else if (this.props.params.surveyId){
getQuestions(this.props.params.surveyId).then(survey => {
// 'survey' contains all the questions
this.setState({
survey,
selectedPreview: survey[0]
});
});
}
}
currentState() {
console.log('clicking Current State');
console.log(this.state.survey[0]);
}
// saves a new survey with associated newly created questions
// or saves an existing survey with associated questions
save() {
console.log('clicking Save');
console.log(this.state.survey[0]);
// if the url is set to survey/new
// save new survey with associated newly created questions
if(this.props.pathname === "/survey/new") {
newSurveyQuestions(this.state.survey).then( id => {
this.context.router.transitionTo(`/survey/id/${id}`);
})
// else update survey and questions
} else {
updateSurveyQuestions(this.state.survey);
}
}
// sets selectedPreview for the entire component and
// its children
setSelectedPreview(selectedPreview) {
this.setState({selectedPreview});
}
render() {
return (
<div className="slds-grid slds-wrap slds-grid--pull-padded">
<SideBar
survey={this.state.survey}
setSelectedPreview={this.setSelectedPreview}
deleteQuestion={this.deleteQuestion}
/>
<MainArea
addQuestion={this.addQuestion}
selectedPreview={this.state.selectedPreview}
update={this.update}
save={this.save}
currentState={this.currentState}
/>
</div>
);
}
}
Survey.contextTypes = {
router: React.PropTypes.object
}
export default Survey;
help function
export function updateSurveyQuestions(survey) {
// create proper url for update request
const requestURL = `${URL + survey[0].attributes.url}`;
// save questions for later update requests
const questions = survey[0].SEO__CSEO_Survey_Questions__r.records;
let s = [...survey];
// remove properties for proper body format
delete s[0].Id;
delete s[0].SEO__CSEO_Survey_Questions__r;
delete s[0].attributes;
axios.patch(requestURL, s[0], API_TOKEN);
questions.forEach( question => {
// save request url for later
let requestURL = `${URL + question.attributes.url }`;
// remove properites for proper body format
delete question.attributes;
delete question.Id;
axios.patch(requestURL, question, API_TOKEN);
})
}
When I removed all the code in save()
, except for the console.log
's, it prints as expected.