【发布时间】:2019-07-13 17:35:17
【问题描述】:
我对我的表单状态应该在哪里生活感到两难。
React 文档提及:
识别基于该状态呈现某些内容的每个组件。 找到一个共同的所有者组件(一个单一的组件高于所有 需要层次结构中状态的组件)。无论是普通 所有者或层次结构中更高的另一个组件应该拥有 状态。如果您找不到一个有意义的组件 state,创建一个简单的新组件来保存状态并添加它 在公共所有者组件上方的层次结构中的某个位置。
我有一个简单的评论 UI。
- 用户在文本区域输入评论。
- 用户在输入字段中输入姓名。
- 用户点击post,下方显示评论。
组件等级如下:
- CommentSection.jsx ---> main (should "Post" state (?))
-comment-post.jsx ---> User Comment Form
- comment-table.jsx
- comment.jsx
- comment-avatar.jsx
- comment-body.jsx
问题: 在comment-post.jsx 中,输入和文本区域有 onChange() 事件处理程序,并且在提交帖子按钮上还有一个单击事件处理程序。我可以选择以下两种方法之一:
- 在
comment-post.jsxonChange 被触发时,将commentBody 发送到CommentSection.jsx这里的问题是我会在用户输入后立即发送commentBody,然后在触发时发送名称等等强> - 在
comment-post.jsx当onChange被触发时SAVE状态中的值,然后命名状态中的字段,当用户点击提交按钮时发送到CommentSection.jsx好处是字段首先设置在状态中,当用户点击他们发送给父母的帖子(应该是正确的?)
评论的输入字段,即commentBody和Name是否应该是 保存在
comment-post.jsx(表单组件)还是父级?
现在我正在执行的状态 2. 在状态中保存表单字段,然后在提交时发送状态值。
我认为问题在于 onChange 和 onClick 是两个不同的处理程序,问题是理想情况下哪个应该将值传递给父组件?
class CommentSection extends Component {
state = {
posts: []
};
handleCommentPost = post => {
const posts = this.state.posts;
posts.push(post);
this.setState({ posts });
};
render() {
console.log("comment:", this.state.posts);
return (
<React.Fragment>
<h1>comments</h1>
<div className="row bootstrap snippets">
<div className="col-md-6 col-md-offset-2 col-sm-12">
<div className="comment-wrapper">
<Comment_Post onClick={this.handleCommentPost} />
<Comment_Table comments={this.state.posts} />
</div>
</div>
</div>
</React.Fragment>
);
}
}
class Comment_Table extends Component {
render() {
const posts = this.props.comments;
let count = 0;
return (
<div className="panel panel-info">
<hr />
<ul className="media-list">
{posts.map(post => (
<Comment key={count++} comment={post.commentBody} />
))}
</ul>
</div>
);
}
}
class Comment extends Component {
render() {
return (
<li className="media">
<Comment_Avatar userAvatar={this.props.commentAvatar} />
<Comment_Body userComment={this.props.comment} />
</li>
);
}
}
class Comment_Body extends Component {
render() {
const { userComment } = this.props;
return (
<div className="media-body">
<span className="text-muted pull-right">
<small className="text-muted">30 min ago</small>
</span>
<strong className="text-success">@MartinoMont</strong>
<p>
{userComment}
{}
</p>
</div>
);
}
}
class Comment_Post extends Component {
state = {
commentBody: null
};
onCommentChange = e => {
this.setState({ commentBody: e.target.value });
};
onCommentPost = e => {
const commentBody = this.state.commentBody;
if (commentBody !== null) {
this.props.onClick({ commentBody });
}
};
onNameInput = e => {};
onCommentPostError() {}
render() {
return (
<React.Fragment>
<div className="panel-heading p-heading">Comment panel</div>
<div className="panel-body">
<textarea
onChange={this.onCommentChange}
className="form-control"
placeholder="write a comment..."
rows="3"
/>
<label htmlFor="fname" onChange={this.onNameInput}>
Name:{" "}
</label>
<input id="fname" placeholder="John" />
<br />
<button
type="button"
className="btn btn-info pull-right"
onClick={this.onCommentPost}
>
Post
</button>
<div className="clearfix" />
</div>
</React.Fragment>
);
}
}
class Comment_Avatar extends Component {
render() {
return (
<a href="#" className="pull-left">
<img
src="https://bootdey.com/img/Content/user_1.jpg"
alt=""
className="img-circle"
/>
</a>
);
}
}
【问题讨论】:
标签: javascript reactjs user-interface components reactive-programming