ReactJS 用于编辑注释
ReactJS for editing comments
我正在尝试弄清楚如何在ReactJS中编辑注释。我一直在遵循本教程。
关于解决方案,我有几种理论:
- 使用可变
state
而不是不可变props
。 - 与具有
loadCommentsFromServer
和handleCommentSubmit
功能的CommentBox
组件有关。loadComments
函数触发一个 AJAX 请求,可能是我的comments.json
文件。
这是server.js
文件中的相关代码
var COMMENTS_FILE = path.join(__dirname, 'comments.json');
app.get('/api/comments', function(req, res) {
fs.readFile(COMMENTS_FILE, function(err, data) {
if (err) { /* Print error to console */ }
res.json(JSON.parse(data));
});
});
// This snippet of code is probably the most important
app.post('/api/comments', function(req, res) {
fs.readFile(COMMENTS_FILE, function(err, data) {
if (err) { /* Print error to console */ }
var comments = JSON.parse(data);
var newComment = {
id: Date.now(),
text: req.body.text,
};
comments.push(newComment);
fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) {
if (err) { /* Print error to console */ }
res.json(comments);
});
});
});
这是我的主脚本文件,我在其中生成反应组件
var Comment = React.createClass({
render: function() {
return (
<div className="comment">
// Trying to change the value of the text box on edit
<p onChange={this.handleTextChange()}> {this.props.text} </p>
</div>
);
}
});
var CommentBox = React.createClass({
首次创建组件时,我们需要从服务器获取JSON
数据,并使用最新数据更新state
。 this.setState()
允许动态更新。旧的注释数组将被新的注释数组所取代
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
此函数将数据从子组件传递到父组件。它应该提交到服务器并刷新评论列表
handleCommentSubmit: function(comment) {
var comments = this.state.data;
comment.id = Date.now();
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: comment,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function(comment) {
return <Comment key={comment.id}>{comment.text}</Comment>
});
return <div className="commentList"> {commentNodes} </div>
);
}
});
这里正在创建一个用于填写表单的组件。 this.state
用于在输入时保存用户的输入。我正在尝试使用编辑功能来实现这一点。
var CommentForm = React.createClass({
getInitialState: function() {
return {text: ''};
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
// This is also probably an important function
handleSubmit: function(e) {
e.preventDefault();
var text = this.state.text.trim();
this.props.onCommentSubmit({text: text});
this.setState({text: ''});
},
输入元素的 value
属性将反映组件的状态,并将onChange
处理程序附加到它们
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" value={this.state.text} onChange={this.handleTextChange} />
<input type="submit" value="Post" />
</form>
);
}
});
最后,我正在渲染CommentBox
组件。url 属性从服务器获取动态数据。pollInterval
每 2 秒重新加载一次页面。
ReactDOM.render(
<CommentBox url="/api/comments" pollInterval={2000} />,
document.getElementById('content')
);
以下是我对如何实现编辑功能的想法
setTimeout(function() {
$('.edit').on('click', function() {
$(this).prev().prop('contentEditable', 'true');
$(this).prev().focus();
});
},1000);
我不得不使用setTimeout
因为加载组件的文件需要一些时间。然后我会监听单击编辑按钮,并将 html5 contentEditable
属性更改为 true。
我遇到的问题是在编辑 JSON 文件后更新对 JSON 文件的更改。
我还想知道是否有一种更反应的方式来完成此点击功能
正如您在组件文件中所看到的,我向呈现文本正文的段落中添加了一个onChange
处理程序。
render: function() {
return (
<div className="comment">
<p onChange={this.handleTextChange()}> {this.props.text} </p>
</div>
);
}
我已经在互联网上广泛搜索了编辑功能的示例,但找不到任何东西。
我的目标是使这段代码尽可能可读。我试图修剪与手头问题不直接相关的代码。我删除了以下代码:
- npm 变量和
app.use
的声明 - 服务器的监听
- 文本表单的作者字段。我们只需要文本字段
让 jQuery 与 React 组件混在一起通常不是一个好主意(尽管 jQuery + React 在某些任务上可以很好地相互配合(; 我们正在运行一个大规模的 React 应用程序,并且花了很多时间从早期删除这个实例。
在保存注释方面,您需要一个新的端点来处理该功能,它看起来应该几乎与app.post('/api/comments')
完全相同,只是它应该从req.body
获取数据,而不是从读取文件中获得data
,这是发布到它的数据。要保持相同的 url this.props.url
您可以将其设置为 PATCH 端点:app.patch('/api/comments' ...)
。我将把这个实现留给你。React 保存功能应该是这样的:Comment
组件应该使用状态来管理它......州。单击"编辑"应将该状态切换为contentEditable
设置为 true,"编辑"变为"保存"等。实际保存部分应在父组件CommentBox
中定义,并应向下传递到Comment
组件。以下是您应该进行哪些更改以允许编辑的基本想法,它是 100% 未经测试的,但希望能有所帮助。
// changes to Comment component
var Comment = React.createClass({
getInitialState: function() {
return {
contentEditable: false,
buttonText: 'Edit',
text: this.props.text
};
},
handleButton: function() {
var commentTag = this.refs.comment;
// if the component is currently editable and the text is different from the original, save it
if (this.state.contentEditable && commentTag.textContent != this.state.text) {
this.props.onUpdateComment(this.props.id, commentTag.textContent);
}
// invert current contentEditable state Save => Edit or Edit => Save
var editable = !this.state.contentEditable;
this.setState({
contentEditable: editable,
// update the state to reflect the edited text
text: commentTag.textContent,
// change button text based on editable state
buttonText: editable ? 'Save' : 'Edit'
});
},
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">{this.props.author}</h2>
<p ref="comment" contentEditable={this.state.contentEditable}>{this.state.text}</p>
<button onClick={this.handleButton}>{this.state.buttonText}</button>
</div>
);
}
});
// changes to CommentList
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function(comment) {
return <Comment onUpdateComment={this.props.onUpdateComment} {...comment} />
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
// changes to CommentBox
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.getJSON(this.props.url)
.then(function(newComments) {
this.setState({ data: newComments });
}.bind(this))
.fail(function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
});
},
handleCommentSubmit: function(comment) {
var comments = this.state.data;
comment.id = Date.now();
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.post(this.props.url, comments)
.then(function(data) {
this.setState({ data: data });
}.bind(this))
.fail(function(xhr, status, err) {
this.setState({ data: comments });
console.error(this.props.url, status, err.toString());
}.bind(this));
},
onUpdateComment: function(id, comment) {
// clone state, we don't want to alter this directly
var newData = this.state.data.slice(0);
newData.forEach(function(item) {
if(item.id === id) {
item.text = comment;
}
});
$.ajax({
url: this.props.url,
dataType: 'json',
method: 'PATCH',
data: newData
}).then(function(data) {
this.setState({ data: data });
}.bind(this));
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
- CKEditor Widget-阻止编辑可编辑元素本身
- 如何在angularJS中编辑时,如果DB中的值为true,则设置复选框,如果值为false,则取消选中复选框
- 高亮显示时编辑文本大小和颜色
- 剑道UI内联编辑:如何在点击其他按钮时隐藏按钮
- 将事件聚焦/模糊在可编辑内容的元素上
- 编辑HTML表的源数据
- ExtJS网格单元格编辑器,防止焦点松动问题
- Javascript中的备选注释方法
- 如何在visualstudio中调试web api时编辑javascript文件
- 具有所有样式的文本正在复制到可编辑文本区域
- html5视频中的Youtube类型注释
- 使用JQuery或Javascript编辑HTML注释文本
- x-editable on按钮,如何编辑特定注释
- 如何在没有注释的情况下从ACE编辑器中获取值
- ReactJS 用于编辑注释
- JavaScript注释编辑功能
- 在文本区域添加注释,并使用“编辑”和“删除”按钮显示文本
- 如何在点击时将HTML标记元素更改为输入文本,以便用户可以编辑注释
- 高亮选择与注释,显示在悬停和可编辑
- 未捕获的类型错误:无法读取属性'作者'在尝试将编辑功能添加到注释框时,为undefined