Reactjs 设置状态数组并在更新时追加值
我仍然在学习ReactJS的状态和生命周期,并且遇到了这样一个场景:我有一个表单,提交时应该保存表单值,然后将返回的JSON对象附加到数组的末尾,该数组将重新呈现存储原始数组的组件 在我当前的设置中,我使用返回的JSON对象设置组件和表单提交,但是状态包含一个空数组,而不是对象排列Reactjs 设置状态数组并在更新时追加值,reactjs,Reactjs,我仍然在学习ReactJS的状态和生命周期,并且遇到了这样一个场景:我有一个表单,提交时应该保存表单值,然后将返回的JSON对象附加到数组的末尾,该数组将重新呈现存储原始数组的组件 在我当前的设置中,我使用返回的JSON对象设置组件和表单提交,但是状态包含一个空数组,而不是对象排列{…comment},并且看起来setState没有更新组件,但这可能是由于前面提到的空数组。谁能给我指出正确的方向吗 评论: import React from 'react'; import fetch from
{…comment}
,并且看起来setState没有更新组件,但这可能是由于前面提到的空数组。谁能给我指出正确的方向吗
评论:
import React from 'react';
import fetch from 'node-fetch';
//record Comment - Comment Form Handle POST
class CommentForm extends React.Component {
constructor(props){
super(props);
this.state = {
value: '',
comments: []
};
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
postComment(comment, recordId, csrfToken) {
var body = { comment: comment };
var route = 'http://localhost:3000/record/' + recordId + '/comment';
fetch(route,
{
method: 'POST',
body: JSON.stringify(body),
headers: {
'X-CSRF-Token': csrfToken,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
let commentsArr = this.state.comments;
this.setState({comments: commentsArr.concat(data)});
})
.catch(err => {
console.log(err);
});
}
onChange(e){
this.setState({
value: e.target.value
});
}
handleSubmit(e){
e.preventDefault();
this.postComment(this.state.value, this.props.recordId, this.props.csrf);
}
render(){
return (
<div className="record-comment__form">
<div className="row">
<form action={"/record/" + this.props.recordId + "/comment"} method="post" onSubmit={this.handleSubmit}>
<input type="hidden" name="_csrf" value={this.props.csrf}/>
<textarea name="comment" className="record-comment__form-text-area" onChange={e => this.setState({ value: e.target.value })} value={this.state.value}></textarea>
<button type="submit" className="record-comment__form-button" disabled={!this.state.value}>Comment</button>
</form>
</div>
</div>
)
}
}
//record Comment - Comment
const Comment = props => {
return (
<div className="row">
<div className="col-md-12">
<h5>{props.user_id}</h5>
<h4>{props.comment}</h4>
<h3>{props.synotate_user.fullNameSlug}</h3>
</div>
</div>
)
}
//record Comment - Container
export default class Comments extends React.Component {
render() {
return (
<div className="record-comment-container">
<CommentForm recordId={this.props.recordId} csrf={this.props.csrf}/>
{ this.props.record_comments.map((comment, i) =>
<Comment {...comment} key={this.props.recordCommentId}/>
)}
</div>
);
}
}
//GET /api/test and set to state
class RecordFeedContainer extends React.Component{
constructor(props, context) {
super(props, context);
this.state = this.context.data || window.__INITIAL_STATE__ || {records: []};
}
fetchList() {
fetch('http://localhost:3000/api/test')
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
this.setState({ records: data.record, user: data.user, csrf: data.csrfToken });
})
.catch(err => {
console.log(err);
});
}
componentDidMount() {
this.fetchList();
}
render() {
return (
<div className="container">
<h2>Comments List</h2>
<RecordFeed {...this.state} />
</div>
)
}
};
//Loop through JSON and create Record and Comment Container Component
const RecordFeed = props => {
return (
<div>
{
props.records.map((record, index) => {
return (
<div className="row">
<div className="col-md-6 col-md-offset-3 record-card">
<RecordCard {...record} key={record.recordIdHash} user={props.user} />
<Comments {...record} key={index} recordId={record.recordIdHash} csrf={props.csrf}/>
</div>
</div>
);
})
}
</div>
)
}
从“React”导入React;
从“节点获取”导入获取;
//记录注释-注释表单句柄POST
类CommentForm扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
值:“”,
评论:[]
};
this.onChange=this.onChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
postComment(注释、记录ID、csrfToken){
var body={comment:comment};
var路由http://localhost:3000/record/“+recordId+”/comment”;
取回(路线),
{
方法:“POST”,
body:JSON.stringify(body),
标题:{
“X-CSRF-Token”:csrfToken,
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”
}
})
。然后(res=>{
返回res.json();
})
。然后(数据=>{
控制台日志(数据);
让commentsArr=this.state.comments;
this.setState({comments:commentsArr.concat(data)});
})
.catch(错误=>{
控制台日志(err);
});
}
onChange(e){
这是我的国家({
价值:即目标价值
});
}
handleSubmit(e){
e、 预防默认值();
this.postComment(this.state.value、this.props.recordId、this.props.csrf);
}
render(){
返回(
this.setState({value:e.target.value})value={this.state.value}>
评论
)
}
}
//记录注释-注释
const Comment=props=>{
返回(
{props.user_id}
{props.comment}
{props.synotate_user.fullNameSlug}
)
}
//记录注释-容器
导出默认类注释扩展React.Component{
render(){
返回(
{this.props.record_comments.map((comment,i)=>
)}
);
}
}
记录(父组件)(设置注释的位置):
import React from 'react';
import fetch from 'node-fetch';
//record Comment - Comment Form Handle POST
class CommentForm extends React.Component {
constructor(props){
super(props);
this.state = {
value: '',
comments: []
};
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
postComment(comment, recordId, csrfToken) {
var body = { comment: comment };
var route = 'http://localhost:3000/record/' + recordId + '/comment';
fetch(route,
{
method: 'POST',
body: JSON.stringify(body),
headers: {
'X-CSRF-Token': csrfToken,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
let commentsArr = this.state.comments;
this.setState({comments: commentsArr.concat(data)});
})
.catch(err => {
console.log(err);
});
}
onChange(e){
this.setState({
value: e.target.value
});
}
handleSubmit(e){
e.preventDefault();
this.postComment(this.state.value, this.props.recordId, this.props.csrf);
}
render(){
return (
<div className="record-comment__form">
<div className="row">
<form action={"/record/" + this.props.recordId + "/comment"} method="post" onSubmit={this.handleSubmit}>
<input type="hidden" name="_csrf" value={this.props.csrf}/>
<textarea name="comment" className="record-comment__form-text-area" onChange={e => this.setState({ value: e.target.value })} value={this.state.value}></textarea>
<button type="submit" className="record-comment__form-button" disabled={!this.state.value}>Comment</button>
</form>
</div>
</div>
)
}
}
//record Comment - Comment
const Comment = props => {
return (
<div className="row">
<div className="col-md-12">
<h5>{props.user_id}</h5>
<h4>{props.comment}</h4>
<h3>{props.synotate_user.fullNameSlug}</h3>
</div>
</div>
)
}
//record Comment - Container
export default class Comments extends React.Component {
render() {
return (
<div className="record-comment-container">
<CommentForm recordId={this.props.recordId} csrf={this.props.csrf}/>
{ this.props.record_comments.map((comment, i) =>
<Comment {...comment} key={this.props.recordCommentId}/>
)}
</div>
);
}
}
//GET /api/test and set to state
class RecordFeedContainer extends React.Component{
constructor(props, context) {
super(props, context);
this.state = this.context.data || window.__INITIAL_STATE__ || {records: []};
}
fetchList() {
fetch('http://localhost:3000/api/test')
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
this.setState({ records: data.record, user: data.user, csrf: data.csrfToken });
})
.catch(err => {
console.log(err);
});
}
componentDidMount() {
this.fetchList();
}
render() {
return (
<div className="container">
<h2>Comments List</h2>
<RecordFeed {...this.state} />
</div>
)
}
};
//Loop through JSON and create Record and Comment Container Component
const RecordFeed = props => {
return (
<div>
{
props.records.map((record, index) => {
return (
<div className="row">
<div className="col-md-6 col-md-offset-3 record-card">
<RecordCard {...record} key={record.recordIdHash} user={props.user} />
<Comments {...record} key={index} recordId={record.recordIdHash} csrf={props.csrf}/>
</div>
</div>
);
})
}
</div>
)
}
//GET/api/test并设置为state
类RecordFeedContainer扩展React.Component{
构造函数(道具、上下文){
超级(道具、背景);
this.state=this.context.data | | window.uu INITIAL_ustate uuu| |{记录:[]};
}
fetchList(){
取('http://localhost:3000/api/test')
。然后(res=>{
返回res.json();
})
。然后(数据=>{
控制台日志(数据);
this.setState({records:data.record,user:data.user,csrf:data.csrfToken});
})
.catch(错误=>{
控制台日志(err);
});
}
componentDidMount(){
这是fetchList();
}
render(){
返回(
评论列表
)
}
};
//循环使用JSON并创建记录和注释容器组件
const RecordFeed=props=>{
返回(
{
道具记录地图((记录,索引)=>{
返回(
);
})
}
)
}
您的问题是,在呈现
时,this.props.record\u注释
不是您在
组件状态下更新的注释。每个组件都有自己的内部状态
您需要将状态传递给
组件。您需要将您的状态向上移动到顶层,或者使用类似的状态管理系统,该系统将允许您访问可能包含注释数组的共享状态
从顶层组件中,您可以管理其中的状态,如下所示:
this.state = {
comments: [],
// other shared state
};
您可以将名为例如updateCommentsFunc()
的updatecomments函数传递给
,如下所示:
这将允许您通过以下方式将更新的注释传递回父组件:
const updateCommentsFunc = (newComments) => {
this.setState({comments: [...this.state.comments, newComments]});
}
您的postComment()
函数似乎未正确绑定到信封
组件的此
。因此;从函数中调用this.setState()
实际上并没有做任何事情
尝试在构造函数方法中绑定它
constructor(props) {
// ...
this.postComment = this.postComment.bind(this)
}
或者通过使用
有关React绑定模式的更多信息,请参阅。您在哪里渲染
,以及如何设置此.props.record\u注释
在该组件上?单独的文件,我将此设置模块化。将更新问题并包含代码您需要共享
的状态,以便在呈现
时可以访问此.state.comments
,谢谢您的精彩解释。那么对这个呢