ReactJS-更新后,子级无法访问父级状态



我在子组件中有一个input field,它是由父组件的状态值预先填充的。

由于我将当前值作为道具和函数传递给子对象以更新父对象中的该值,因此每当我从传递的函数更新父对象时,我的子对象似乎都突然无法访问父状态。

我父母的状态:

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':""
}
},
})

传递给子级的函数:

const _getBlockContent = (
currentBlockKey, 
contentKey, 
returnedContent
) => {
setBlockList(blockList[currentBlockKey].content[contentKey] = returnedContent)
}

我传递给孩子的东西:

return (    
<Child
currentBlock={blockList[selectedBlock]} // (i.e. selectedBlock = '1')
_getBlockContent={_getBlockContent}
currentBlockKey={selectedBlock} // (i.e. selectedBlock = '1')
/> )

现在,每当我将输入保存在子对象中并使用函数_getBlockContent更新父对象的状态时,就会导致我的子对象中断。

TypeError: props.currentBlock.content is undefined

完整子级(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>
);
}
}

_getBlockContent函数中,用returnedContent替换整个状态,而只需要替换要更新的密钥:

const _getBlockContent = (
currentBlockKey, 
contentKey, 
returnedContent
) => {
const newBlockList = {
...blockList,
[currentBlockKey]: {
...blockList[currentBlockKey],
[contentKey]: returnedContent,
}
};
setBlockList(newBlockList);
}

由于_getBlockContent实际上会更新状态,因此应该考虑将其重命名为类似setBlockContentonBlockContentChanged的名称,以使其比执行写入而非读取更清楚

我看到了一些东西。

根据您的命名,_getBlockContent(..)用于检索状态。请注意,setBlockList(..)并非用于读取状态,它仅用于更新状态。为了读取状态,您可以直接在功能组件_getBlockContent(..)中使用blockList,如下所示。

return blockList[currentBlockKey].content[contentKey];

除此之外,为了在我端积极复制您的错误,您是否可以共享一个github链接或包含逻辑中所有组件的东西(包括<Editor>等(?

最新更新