I have an input field in a child component that is prefilled from the value of a parent's state.
Since I pass the current value to the child as a prop and a function to update this value in the parent, it seems that whenever I update the parent from the passed function, my child is suddenly not able to access the parent state.
My parent's state:
const [blockList,setBlockList] = useState({
"0":{
type:"loading",
content:{
'title':"placeholder_title",
'description':"placeholder_description"
}
},
"1":{
type:"description",
content:{
'title':"placeholder_title",
'description':"placeholder_description"
}
},
"2":{
type:"skills_and_requirements",
content:{
'title':"",
'description':""
}
},
})
The function passed to the child:
const _getBlockContent = (
currentBlockKey,
contentKey,
returnedContent
) => {
setBlockList(blockList[currentBlockKey].content[contentKey] = returnedContent)
}
What I pass to the child:
return (
<Child
currentBlock={blockList[selectedBlock]} // (i.e. selectedBlock = '1')
_getBlockContent={_getBlockContent}
currentBlockKey={selectedBlock} // (i.e. selectedBlock = '1')
/> )
Now, whenever I save the input in the child and use the function _getBlockContent to update the state of my parent, this causes my Child to break.
TypeError: props.currentBlock.content is undefined
Full child (draftJS) :
const EditorPanel = (props) => {
//receives the block from the parent. The block type will define the advice and other static elements of the pannel. The block content will define what to include in the input and editor fields.
//This function should be passed to the editor and update the block content.
const _getEditorContent = (contentKey, returnedContent) => {
console.log("contentKey is: %s", contentKey);
console.log("returnedContent is: %s", returnedContent);
props._getBlockContent(props.currentBlockKey,contentKey, returnedContent)
}
return(
<div className="edit_panel">
<div className="edit_panel_container">
<h2>Description</h2>
<h3>Title</h3>
<MyEditor
contentKey={'title'}
contentValue={props.currentBlock.content['title']}
_getEditorContent={_getEditorContent}
/>
<p>Title of this section should be eiusmod dolor sit amet, consectetur.</p>
<h3>Description</h3>
<MyEditor
contentKey={'description'}
contentValue={props.currentBlock.content['description']}
_getEditorContent={_getEditorContent}
/>
<p
>Title of this section should be eiusmod dolor sit amet, consectetur.</p>
<p>Title of this section should be eiusmod dolor sit amet, consectetur.</p>
</div>
</div>
);
};
class MyEditor extends React.Component {
constructor(props) {
super(props);
//this.state = {editorState: EditorState.createEmpty()};
this.state = {editorState: EditorState.createWithContent(
stateFromHTML(props.contentValue)
)};
this.onChange = editorState => {
this.setState({editorState});
//this.returnEditorHTML()
}
this.handleKeyCommand = this.handleKeyCommand.bind(this);
this.focus = () => this.editor.focus();
this.returnEditorHTML = editorState => {
const content = stateToHTML(this.state.editorState.getCurrentContent());
props._getEditorContent(props.contentKey,content);
};
}
handleKeyCommand(command, editorState) {
const newState = RichUtils.handleKeyCommand(editorState, command);
if (newState) {
this.onChange(newState);
return 'handled';
}
return 'not-handled';
}
_onBoldClick() {
this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'));
}
_onItalicClick() {
this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'ITALIC'));
}
_onUnderlineClick() {
this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'UNDERLINE'));
}
render() {
return (
<div>
<div className="draft_input">
<Editor
editorState={this.state.editorState}
handleKeyCommand={this.handleKeyCommand}
onChange={this.onChange}
/>
</div>
<button onClick={this._onItalicClick.bind(this)}>I<i className="fas fa-bold"></i></button>
<button onClick={this._onBoldClick.bind(this)}>B</button>
<button onClick={this._onUnderlineClick.bind(this)}>U</button>
<button onClick={this.returnEditorHTML}>save</button>
<div></div>
</div>
);
}
}