-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hm4 kazmin #40
base: master
Are you sure you want to change the base?
Hm4 kazmin #40
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import React, { Component } from 'react' | ||
import PropTypes from 'prop-types' | ||
import { connect } from 'react-redux' | ||
import CommentHolder from '../entities/CommentHolder' | ||
import { addComment } from '../ac' | ||
|
||
class AddCommentForm extends Component { | ||
state = { | ||
user: '', | ||
text: '' | ||
} | ||
|
||
static propTypes = { | ||
commentHolder: PropTypes.instanceOf(CommentHolder).isRequired, | ||
addComment: PropTypes.func.isRequired | ||
} | ||
|
||
render() { | ||
return ( | ||
<form> | ||
<label> | ||
User name: | ||
<input | ||
placeholder="User name" | ||
name="user" | ||
onChange={this.handleUserChange} | ||
value={this.state.user} | ||
/> | ||
</label> | ||
<label> | ||
Comment : | ||
<textarea | ||
placeholder="Comment text" | ||
name="comment" | ||
onChange={this.handleCommentChange} | ||
value={this.state.text} | ||
/> | ||
</label> | ||
<button type="button" onClick={this.handleAddClick}> | ||
add | ||
</button> | ||
</form> | ||
) | ||
} | ||
|
||
handleUserChange = (e) => { | ||
e.preventDefault() | ||
e.stopPropagation() | ||
|
||
this.setState({ user: e.target.value }) | ||
} | ||
|
||
handleCommentChange = (e) => { | ||
e.preventDefault() | ||
e.stopPropagation() | ||
|
||
this.setState({ text: e.target.value }) | ||
} | ||
|
||
handleAddClick = (e) => { | ||
e.preventDefault() | ||
e.stopPropagation() | ||
|
||
this.props.addComment(this.props.commentHolder, { | ||
...this.state | ||
}) | ||
|
||
this.setState({ | ||
text: '' | ||
}) | ||
} | ||
} | ||
|
||
export default connect(null, { | ||
addComment | ||
})(AddCommentForm) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
const TYPE_ARTICLE = Symbol('TYPE_ARTICLE') | ||
|
||
export default class CommentHolder { | ||
static get TYPE_ARTICLE() { | ||
return TYPE_ARTICLE | ||
} | ||
|
||
constructor(id, type = CommentHolder.TYPE_ARTICLE) { | ||
if (typeof id !== 'string' || id.length === 0) { | ||
throw new TypeError('id should be a not empty string') | ||
} | ||
|
||
if (type !== CommentHolder.TYPE_ARTICLE) { | ||
throw new TypeError('type should be equal TYPE_ARTICLE') | ||
} | ||
|
||
this._id = id | ||
this._type = type | ||
} | ||
|
||
getId() { | ||
return this._id | ||
} | ||
|
||
getType() { | ||
return this._type | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { ADD_COMMENT } from '../constants' | ||
import generateId from 'uuid/v1' | ||
|
||
export default (store) => (next) => (action) => { | ||
const { type, payload } = action | ||
|
||
if (type === ADD_COMMENT) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. через мидлвары будет проходить каждый экшин, они должны быть максимально общими, завязывать на конкретные экшины - не лучшее решение There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. тогда просто подмешивать в каждый екшене в payload generatedId ? |
||
payload.comment = { | ||
...payload.comment, | ||
id: generateId() | ||
} | ||
} | ||
|
||
next(action) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,43 @@ | ||
import { DELETE_ARTICLE } from '../constants' | ||
import { normalizedArticles as defaultArticles } from '../fixtures' | ||
import { DELETE_ARTICLE, ADD_COMMENT } from '../constants' | ||
import { normalizedArticles } from '../fixtures' | ||
import CommentHolder from '../entities/CommentHolder' | ||
|
||
const defaultArticles = normalizedArticles.reduce( | ||
(acc, article) => ({ | ||
...acc, | ||
[article.id]: article | ||
}), | ||
{} | ||
) | ||
|
||
export default (articleState = defaultArticles, action) => { | ||
const { type, payload } = action | ||
|
||
switch (type) { | ||
case DELETE_ARTICLE: | ||
return articleState.filter((article) => article.id !== payload.id) | ||
delete articleState[payload.id] | ||
|
||
return { | ||
...articleState | ||
} | ||
|
||
case ADD_COMMENT: | ||
if (payload.holder.getType() === CommentHolder.TYPE_ARTICLE) { | ||
const articleId = payload.holder.getId() | ||
const article = articleState[articleId] | ||
|
||
article.comments = [].concat(article.comments) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. article тоже по ссылке не меняй There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. лучшее решение думаю deepClone (lodash), и в коменты подмешивать новый commentId ну и если говорить о разбиении, comments - не лучшний нейминг, скорее commentIds |
||
article.comments.push(payload.comment.id) | ||
|
||
return { | ||
...articleState, | ||
[articleId]: { | ||
...article | ||
} | ||
} | ||
} else { | ||
return articleState | ||
} | ||
|
||
default: | ||
return articleState | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Как по мне - перемудрил с этим. Тем более ты пользуешься тем, что у нас key={id}, но ты не можешь быть в этом уверен в самом компоненте.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тогда можно просто передавать entityId + entityOwner (entityHolder, etc.)
потому что если мы не будем делать абстракцию и потом компонент коментариев будет использоватся например списком новостей, прийдется компонент коментариев рефакторить