我有一个评论表单,可以添加评论,但是我必须刷新页面才能显示它们
评论表单如下所示
class CommentForm extends PureComponent {
constructor(props) {
super(props);
this.state = {
state: this.props.state
};
this.handleChange = this.handleChange.bind(this);
}
handleSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.state);
};
handleChange = event => {
const { name, value } = event.target;
this.setState({
[name]: value
});
};
render() {
return (
<div>
<Paper className="styles" elevation={4}>
<form onSubmit={this.handleSubmit}>
<div>
<TextField
label="Comment"
name="comment"
value={this.state.comment || ""}
onChange={this.handleChange}
/>
</div>
<br />
<Button type="submit">Save</Button>
</form>
</Paper>
</div>
);
}
}
const mapStateToProps = state => {
return {
state: state
};
};
export default connect(
mapStateToProps,
{ getTicket }
)(CommentForm);
该组件用于显示保存在数据库中的注释 displayComments
class DisplayComments extends PureComponent {
componentWillMount() {
this.props.getAllComments();
}
getComment(commentId) {
this.props.getComment(commentId);
}
render() {
const { comments } = this.props;
const commentsOnTicket = this.props.data.match.params.id
const filterComments = comments.filter(comment => comment.tickets.id == commentsOnTicket);
const commentsList = filterComments.sort((a, b) => {
return a.id - b.id;
});
return (
<div>
<Paper className="styles" elevation={4}>
<h1>comments</h1>
<table>
<thead />
<tbody>
{commentsList.map(comment => (
<tr key={comment.id}>
<td style={{ border: "2px solid black" }}>
{comment.comment}
</td>
<td />
</tr>
))}
</tbody>
</table>
<br />
<br />
</Paper>
</div>
);
}
}
const mapStateToProps = (state, props) => {
return {
comments: state.comments,
comment: state.comment,
users: state.users === null ? null : state.users,
};
};
export default connect(
mapStateToProps,
{
getAllComments,
getComment,
}
)(DisplayComments);
我对React的了解有限,因为我刚开始学习它 所以我想应该通过生命周期挂钩来完成 但是我还不太了解它们。
这是父母组件,用于呈现评论表格并显示评论
class TicketDetails extends PureComponent {
componentWillMount() {
this.props.getAllComments();
}
addComment = comment => {
this.props.addComment(comment);
};
render() {
const { ticket, tickets, comments } = this.props;
const { users } = ticket;
return <div>
<Card className="outer-card">
<h1>Ticket: {ticket.id}</h1>
<h2>Price: €{ticket.price}</h2>
<p>Description: {ticket.description}</p>
<h2>Image: {ticket.image}</h2>
<p>Risk: {getRiskfactor(tickets, ticket, users, comments)} %</p>
<hr />
</Card>
<DisplayComments data={this.props} />
<CommentForm onSubmit={this.addComment} />
</div>;
}
}
const mapStateToProps = state => {
return {
ticket: state.ticket,
users: state.users,
tickets: state.tickets,
comments: state.comments
};
};
export default connect(
mapStateToProps,
{
addComment,
getAllComments
}
)(TicketDetails);
TicketDetails 在 App 组件中呈现
class App extends Component {
render() {
return (
<Router>
<div>
<TopBar />
<br/><br/>
<Route exact path="/login" component={LoginPage} />
<Route exact path="/logout" component={LogoutPage} />
<Route exact path="/signup" component={SignupPage} />
<Route exact path="/events" component={EventsList} />
<Route exact path="/addEvent" component={AddEvent} />
<Route exact path="/events/:id" component={TicketsList} />
<Route exact path="/tickets/:id" component={TicketDetails} />
<Route exact path="/addTicket" component={AddTicket} />
<Route exact path="/" render={() => <Redirect to="/events" />} />
</div>
</Router>
);
}
}
Action / comments.js
import * as request from "superagent";
import {baseUrl} from "../constants";
import {logout} from "./users";
import {isExpired} from "../jwt";
export const GET_ALL_COMMENTS = "GET_ALL_COMMENTS";
export const GET_COMMENT = "GET_COMMENT";
export const ADD_COMMENT = "ADD_COMMENT";
export const getAllComments = () => (dispatch, getState) => {
const state = getState();
if (!state.currentUser) return null;
const jwt = state.currentUser.jwt;
if (isExpired(jwt)) return dispatch(logout());
request
.get(`${baseUrl}/comments`)
.set("Authorization", `Bearer ${jwt}`)
.then(response =>
dispatch({
type: GET_ALL_COMMENTS,
payload: response.body.comments
})
)
.catch(err => alert(err));
};
export const getComment = commentId => (dispatch, getState) => {
const state = getState();
if (!state.currentUser) return null;
const jwt = state.currentUser.jwt;
if (isExpired(jwt)) return dispatch(logout());
request
.get(`${baseUrl}/comments/${commentId}`)
.set("Authorization", `Bearer ${jwt}`)
.then(response =>
dispatch({
type: GET_COMMENT,
payload: response.body
})
)
.catch(err => alert(err));
};
export const addComment = comment => (dispatch, getState) => {
const state = getState();
const jwt = state.currentUser.jwt;
if (isExpired(jwt)) return dispatch(logout());
request
.post(`${baseUrl}/comments`)
.set("Authorization", `Bearer ${jwt}`)
.send({
comment: comment.comment,
tickets: state.ticket
})
.then(response =>
dispatch({
type: ADD_COMMENT,
payload: response.body
})
);
};
reducers / comments.js
import { GET_ALL_COMMENTS } from "../actions/comments";
export default function(state = [], action) {
switch (action.type) {
case GET_ALL_COMMENTS:
return action.payload;
default:
return state;
}
}
reducers / comment.js
import { GET_COMMENT,ADD_COMMENT } from "../actions/comments";
const comment = {};
export default function(state = comment, action) {
switch (action.type) {
case GET_COMMENT:
return action.payload;
case ADD_COMMENT:
return action.payload;
default:
return state;
}
}
答案 0 :(得分:2)
尽管您的问题似乎不完整,但在实现上仍然存在一些错误。
您尚未正确使用道具进行派遣。这是为了将分派连接到您的函数,这样您就不必在函数中显式调用this.props.dispatch(func())
const mapDispatchToProps = (dispatch) => {
return {
addComment: (comment) => dispatch(addComment(comment))
}
}
将道具传递到两到三个级别似乎不是一个好习惯。由于您的课程是静态课程,因此您可以轻松地在您的组件中获取它,甚至可以轻松调用它。
为什么要采取措施从存储中获取数据。动作和简化程序应在存储中进行更改,例如添加,删除和更新,而不是用于获取数据。为了获取数据,您需要将状态连接到道具。
更新****
// Add import of the action here like import {addComment} from '../.whatever';
class TicketDetails extends PureComponent {
componentWillMount() {
this.props.getAllComments();
}
addComment = comment => {
this.props.addComment(comment);
};
render() {
const { ticket, tickets, comments } = this.props;
const { users } = ticket;
return <div>
<Card className="outer-card">
<h1>Ticket: {ticket.id}</h1>
<h2>Price: €{ticket.price}</h2>
<p>Description: {ticket.description}</p>
<h2>Image: {ticket.image}</h2>
<p>Risk: {getRiskfactor(tickets, ticket, users, comments)} %</p>
<hr />
</Card>
<DisplayComments data={this.props} />
<CommentForm onSubmit={this.addComment} />
</div>;
}
}
const mapStateToProps = state => {
return {
ticket: state.ticket,
users: state.users,
tickets: state.tickets,
comments: state.comments
};
};
const mapDispatchToProps = (dispatch) => {
return {
addComment: (comment) => dispatch(addComment(comment)),
getAllComments: () => dispatch(getAllComments())
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(TicketDetails);