我正在使用draft.js
一个文本编辑器,我有两个组件:CreatePost.js
它从后端获取post字段,并用用户输入填充状态,并且TextEditor.js
包含一个我正在in中使用的文本编辑器CreatePost.js
。文本编辑器应body
以CreatePost.js
onChange状态填充该字段。
我的问题是如何让文本编辑器填充其他组件中的状态?我需要使用道具吗?
之前,我有一个文本区域,CreatePost.js
其中填充body
。我希望其他组件中的文本编辑器代替它。我试过使用<TextEditor onChange={this.changeHandler} value={body} />
in,CreatePost.js
但没有用。
posts.js(控制器)
exports.create = (req, res) => {
const { title, body, date } = req.body;
const post = new Post({
title,
body,
date,
"author.id": req.profile._id,
"author.name": req.profile.name,
});
post
.save()
.then((response) => {
res.send(response);
})
.catch((err) => {
return res.status(400).json({
error: errorHandler(err),
});
});
};
CreatePost.js
class CreatePost extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "",
body: "",
createdPost: "",
error: "",
};
}
changeHandler = (e) => {
this.setState({ [e.target.name]: e.target.value });
};
submitHandler = (e) => {
e.preventDefault();
const {
user: { _id },
} = isAuthenticated();
axios({
url: `${API}/post/new-post/${_id}`,
method: "POST",
data: this.state,
})
.then((response) => {
this.setState({ createdPost: this.state.title });
return response;
})
.catch((error) => {
if (!this.state.title || !this.state.body) {
this.setState({
error: "This post must contain a title and a body.",
});
}
console.log(error);
});
};
...
render() {
const { title, body } = this.state;
return (
<>
<Navbar />
<Tabs>
<TabList className="tabs">
<Tab className="tab">Draft</Tab>
<Tab className="tab">Preview</Tab>
</TabList>
<TabPanel>
<div className="newpost_container">
<form className="newpost_form" onSubmit={this.submitHandler}>
<div className="form-group">
<input
type="text"
placeholder="Title"
name="title"
className="newpost_field newpost_title"
onChange={this.changeHandler}
value={title}
/>
</div>
<div className="form-group newpost_body">
<TextEditor />
</div>
<button className="btn publish-post-btn" type="submit">
Publish
</button>
{this.showSuccess()}
{this.showError()}
</form>
</div>
</TabPanel>
<TabPanel>
<div>
<h1>{title}</h1>
<div>{body}</div>
</div>
</TabPanel>
</Tabs>
</>
);
}
}
export default CreatePost;
TextEditor.js
class TextEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty(),
};
this.plugins = [addLinkPlugin];
}
toggleBlockType = (blockType) => {
this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType));
};
onChange = (editorState) => {
this.setState({
editorState,
});
};
handleKeyCommand = (command) => {
const newState = RichUtils.handleKeyCommand(
this.state.editorState,
command
);
if (newState) {
this.onChange(newState);
return "handled";
}
return "not-handled";
};
// onClick for format options
onAddLink = () => {
const editorState = this.state.editorState;
const selection = editorState.getSelection();
const link = window.prompt("Paste the link -");
if (!link) {
this.onChange(RichUtils.toggleLink(editorState, selection, null));
return "handled";
}
const content = editorState.getCurrentContent();
const contentWithEntity = content.createEntity("LINK", "MUTABLE", {
url: link,
});
const newEditorState = EditorState.push(
editorState,
contentWithEntity,
"create-entity"
);
const entityKey = contentWithEntity.getLastCreatedEntityKey();
this.onChange(RichUtils.toggleLink(newEditorState, selection, entityKey));
};
toggleBlockType = (blockType) => {
this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType));
};
render() {
return (
<div className="editorContainer">
<div className="toolbar">
<BlockStyleToolbar
editorState={this.state.editorState}
onToggle={this.toggleBlockType}
/>
// format buttons
</div>
<div>
<Editor
placeholder="Post Content"
blockStyleFn={getBlockStyle}
editorState={this.state.editorState}
handleKeyCommand={this.handleKeyCommand}
onChange={this.onChange}
plugins={this.plugins}
placeholder="Post Content"
/>
</div>
</div>
);
}
}
export default TextEditor;
看来您实际上已经很接近解决这个问题了。使用props将变更处理程序发送到时,您走在正确的道路上TextEditor
。其中一个解决问题的方法是向上移动editorState
到你的CreatePost
组件,然后传递值和更改处理向下。如果执行此操作,则应从TextEditor
文件中删除editorState及其更改处理程序。仅通过继续执行您的示例,这样的方法就可以了,我还没有尝试过代码,但是它可以帮助您朝正确的方向发展。
在 CreatePost.js
constructor(props) {
super(props);
this.state = {
title: "",
body: EditorState.createEmpty(),
createdPost: "",
error: "",
};
}
....
<TextEditor onChange={(value) => this.setState({ body: value })} editorState={body} />
在 TextEditor.js
<Editor
placeholder="Post Content"
blockStyleFn={getBlockStyle}
editorState={this.props.editorState}
handleKeyCommand={this.handleKeyCommand}
onChange={this.props.onChange}
plugins={this.plugins}
placeholder="Post Content"
/>
发布数据时,我们需要访问编辑器的内容而不是EditorState
。我们可以通过draft.js API来做到这一点(在此处查看更多信息:https ://draftjs.org/docs/api-reference-editor-state/#getcurrentcontent )。不幸的是,这还不够。我们还需要将内容转换为更易于处理的格式。我们可以使用draft.js做到这一点convertToRaw
,您还需要从库(https://draftjs.org/docs/api-reference-data-conversion/#converttoraw)中导入该文件。Convert to raw返回一个JS对象,因此我们还需要先将该对象转换为字符串,然后才能使用将其发送到服务器JSON.stringify()
。
axios({
url: `${API}/post/new-post/${_id}`,
method: "POST",
data: {
...this.state,
body: JSON.stringify(convertToRaw(this.state.body.getCurrentContent()))
}
})
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句