我对表格状态应该居住的位置感到困惑。
回复文档提及:
识别根据该状态呈现内容的每个组件。 找到一个共同的所有者组成部分(所有 需要层次结构中的状态的组件)。共同点 所有者或层次结构中更高级别的其他组件应拥有 州。如果找不到合适的组件 状态,创建一个仅用于保存状态的新组件并添加它
我有一个简单的注释UI。
组件高度如下:
- 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
中,input和textarea字段具有onChange()事件处理程序,并且submit post按钮上还具有click事件处理程序。我可以选择执行以下两项之一:
comment-post.jsx
中,当触发onChange时,将commentBody发送到CommentSection.jsx
,这里的问题是,我将在用户键入内容后立即发送commentBody,然后在触发时发送名称,然后等等 comment-post.jsx
中,当触发onChange时,将状态保存到状态,然后在状态中命名名称字段,当用户单击提交按钮发送到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>
);
}
}
答案 0 :(得分:0)
我认为问题是onChange和onClick是两个不同的处理程序,问题是哪个值应该理想地传递给父组件?
我们在标准用户界面设计中使用两种类型的表单。首先是输入中的任何更改都会保存更改。其次,在对“表单元素”进行更改后,请按下“提交”按钮,然后保存更改。
由于您已经实现了第二种类型,因此onChange
应该处理控制TextArea状态,而onClick
应该处理提交。这样您的代码就可以了。
我对表格状态应该居住的位置感到困惑。
这取决于...在您的情况下,您只有一个表单,并且两个表单元素都不可重复使用。因此,这些不受控制的表单非常适合您。但是,如果您想拥有一个可重用的表单组件,或者想拥有一个包含15个字段的表单,则您不想为每个组件编写单独的onChange处理程序。为此,您需要制作一个可控制的表单组件,该组件可以为您处理所有这些事情。这是一个示例。
export default class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
values: {}
};
}
@boundMethod
handleSubmit(event) {
event.preventDefault();
this.props.submit(this.state.values);
}
@boundMethod
handleChange(event) {
const { name, value } = event.target;
const newValues = Object.assign(
{ ...this.state.values },
{ [name]: value }
);
this.setState({
values: newValues
});
}
public render() {
const { values } = this.state;
return (
<form onSubmit={this.handleSubmit} noValidate={true}>
<div>
{React.Children.map(
this.props.children,
child => (
{React.cloneElement(child, {
value: values[child.props.name],
onChange: this.handleChange
})}
)
)}
<div>
<button type="submit">
Submit
</button>
</div>
</div>
</form>
);
}
}
然后您将可以像下面这样使用Form类:
<Form
submit={values => {
/* work with values */
}}
>
<input type="hidden" name="name" />
<input type="hidden" name="rating" />
</Form>;