我可以点击编辑评论,它会将我带到评论编辑页面,其中包含该评论的值。问题是,如果我点击刷新它打破了页面,我得到错误评论未定义。现在我知道这是因为国家已被抹去,但有没有办法解决这个问题,我可以等到国家加载或等等?
更新:我已经修复了破解刷新的页面但我无法获取initialValues来获取评论值。我不确定以后是否有办法设置状态值。我收到author
未定义和_id
未定义的内容,我知道这是因为我将commentValue
设置为{}
。我的问题是,当状态确实正确更新以获得这些值时,有一种方法吗?
以下是支票代码:
function mapStateToProps({ posts, auth, user }, ownProps) {
let commentValue = {};
const post = posts[ownProps.match.params.id];
if(!post){
return commentValue = {};
}
if(!posts.comments[ownProps.match.params.comment_id]) {
return commentValue = {};
}
if(posts.comments[ownProps.match.params.comment_id]){
return commentValue = posts.comments[ownProps.match.params.comment_id];
}
return {
initialValues: commentValue,
post: posts[ownProps.match.params.id],
auth: auth.authenticated,
user: user
};
}
以下是代码:
import React , { Component } from 'react';
import * as actions from '../../actions/comments_actions';
import { bindActionCreators } from 'redux';
import * as actionsPosts from '../../actions/posts_actions';
import * as actionsIndex from '../../actions/index';
import { reduxForm, Field } from 'redux-form';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom';
class EditComment extends Component {
componentDidMount() {
const {id, comment_id} = this.props.match.params;
this.props.getOnePost(id);
if(this.props.user._id !== this.props.post.comments[comment_id].author.id) {
this.props.history.replace(`/posts/${id}`);
}
if(this.props.auth) {
this.props.getUser();
}
}
componentWillReceiveProps ({ user: nextUser, history, match, post, auth}) {
const {user: currentUser} = this.props;
const { id } = match.params
if (!currentUser || nextUser !== currentUser) {
if (nextUser && (nextUser._id !== post.author.id)) {
history.replace(`/posts/${id}`);
}
}
}
renderField(field) {
const { meta: {touched, error} } = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className={className}>
<label><strong>{field.label}:</strong></label>
<input
className="form-control"
type={field.type}
{...field.input}
/>
<div className="text-help">
{ touched ? error : ''}
</div>
</div>
)
}
onSubmit(values) {
const {comment_id} = this.props.match.params;
this.props.editComment(values, comment_id, () => {
this.props.history.push(`/posts/${id}`);
});
}
render() {
const {handleSubmit} = this.props;
const {id} = this.props.match.params;
return (
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Comment"
name="text"
type="text"
component={this.renderField}
/>
<button type="submit" className="btn btn-success">Comment</button>
<Link to={`/posts/${id}`} className="btn btn-danger">Cancel</Link>
</form>
);
}
}
function validate(values) {
const errors = {};
if(!values.comment) {
errors.comment = "Enter a comment!";
}
return errors;
}
function mapStateToProps({ posts, auth, user }, ownProps) {
console.log(posts[ownProps.match.params.id]);
const commentValue = posts[ownProps.match.params.id].comments[ownProps.match.params.comment_id];
console.log(commentValue);
return {
initialValues: commentValue,
post: posts[ownProps.match.params.id],
auth: auth.authenticated,
user: user
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({...actions, ...actionsIndex, ...actionsPosts}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(reduxForm({
validate,
form: 'editform'
})(EditComment));
答案 0 :(得分:0)
听起来发生的事情是您的路由逻辑确保在您刷新该URL的页面时显示此组件,但您的应用程序没有加载该组件所需的数据。
这基本上与Dave Ceddia在帖子Watch Out for Undefined State中描述的问题相同。如果有可能在您需要的数据可用之前呈现其中一个组件,则应编写代码来处理该情况。有几种方法可以做到这一点,Dave在他的帖子中展示了一些例子。
在您的特定情况下,您的mapState
函数正在尝试取消引用一些非常嵌套的状态:
const commentValue = posts[ownProps.match.params.id].comments[ownProps.match.params.comment_id];
您应该将其分解为几个步骤,然后进行防御性检查以查看是否首先存在具有该ID的帖子,如果存在,则是否存在具有该ID的评论。如果他们不这样做,您可能希望从null
返回undefined
或mapState
该道具。
答案 1 :(得分:0)
在markerikson的帮助下,我能够找到解决方案。在mapStateToProps
中,我做了一些检查,并在状态将返回undefined的情况下设置一些初始值。这是工作代码:
function mapStateToProps({ posts, auth, user }, ownProps) {
let commentValue = {};
const {id, comment_id} = ownProps.match.params;
if(!posts.comments){
commentValue = null;
}
if(posts[id]){
if(posts[id] && posts[id].comments[comment_id]){
commentValue = posts[id].comments[comment_id];
}
}
return {
initialValues: commentValue,
post: posts[ownProps.match.params.id],
auth: auth.authenticated,
user: user
};
}