blog
がブログをuser
できるedit
を作成しています。ここで、データをモーダルにポップして、これをedit
..にします。
それで、結局デバッグとより良い考えの後で、私はこれを理解しました。これは、modal
の私の更新された作業コードです
お時間をいただきありがとうございます。
//blog.js
class Blogs extends Component{
constructor(props) {
super(props);
this.state = {
modal: false,
justClicked: null,
activePage: 1,
requiredItem : null,
_id: '',
blog_short_desc:'',
blog_name: '',
blog_desc: '',
blog_image_link: '',
blog_by: '',
blog_by_author: ''
};
this.handleOpenDialog = this.handleOpenDialog.bind(this);
this.handleCloseDialog = this.handleCloseDialog.bind(this);
this.replaceModalItem = this.replaceModalItem.bind(this);
this.onTodoChange = this.onTodoChange.bind(this);
}
static propTypes = {
getBlog: PropTypes.func.isRequired,
deleteBlog: PropTypes.func.isRequired,
updateBlog: PropTypes.func.isRequired,
resume: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired,
loading: PropTypes.object.isRequired
}
toggle = (id) => {
this.setState({
modal: !this.state.modal
});
}
componentDidMount() {
this.props.getBlog();
}
replaceModalItem(id, blog_short_desc, blog_name , blog_desc, blog_image_link, blog_by, blog_by_author) {
this.setState({
modal: true,
requiredItem: id,
_id: id,
blog_short_desc: blog_short_desc,
blog_name: blog_name,
blog_desc: blog_desc,
blog_image_link: blog_image_link,
blog_by: blog_by,
blog_by_author: blog_by_author
});
}
onTodoChange = (e) => {
this.setState({
[e.target.name] : e.target.value
});
}
onSubmit = (e, id) => {
e.preventDefault();
const updatedBlog = {
blog_short_desc: this.state.blog_short_desc,
blog_name: this.state.blog_name,
blog_desc: this.state.blog_desc,
blog_image_link: this.state.blog_image_link,
blog_by: this.props.auth["user"]._id,
blog_by_author: this.props.auth["user"].name
}
//update blog via updateblog action
this.props.updateBlog(id, updatedBlog);
alert("Blog updated successfully!");
e.target.reset();
this.toggle();
window.location.reload();
}
handleOpenDialog(id) {
this.setState({
openDialog: true,
OpenEditDialog: true,
justClicked: id
});
}
handleCloseDialog() {
this.setState({
openDialog: false
});
}
onDeleteBlogClick = (id) => {
this.props.deleteBlog(id);
};
handlePageChange(pageNumber) {
this.setState({activePage: pageNumber});
}
render(){
const { blogs, loading} = this.props.resume;
const { user, isAuthenticated } = this.props.auth;
const itemsPerPage = 6;
let activeBlogs = blogs.slice (itemsPerPage * this.state.activePage - itemsPerPage, itemsPerPage * this.state.activePage);
return(
<Container>
{loading ? (
<div><Loading/></div>
) : (
<div>
{/* blog modal */}
<BlogModal />
{/* card dialog */}
<BlogData blogs={blogs} user={this.props.auth} handleCloseDialog={this.handleCloseDialog} {...this.state} toggle={this.toggle}/>
{/* edit card dialog */}
<EditBlog onTodoChange={this.onTodoChange} {...this.state} toggle={this.toggle} onSubmit={this.onSubmit}/>
<Grid style={{padding: 0}} className="blog-grid">
{activeBlogs.map((item, i) => (
<Cell key={item._id} data-id={item._id} className="blog-grid-cell">
<Card shadow={5} className="cards-grid">
{item.blog_image_link ?
(<CardTitle style={{color: '#fff', height: '200px',
width: 'auto', backgroundImage: `url(${item.blog_image_link})`, backgroundPosition: 'center',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat'}}></CardTitle>) :
(<CardTitle className="card-title-image"></CardTitle>
)
}
<CardText>
<b>{item.blog_short_desc}</b>
</CardText>
<CardActions border>
<p className="block-data-details">
<Button className="blog-read-me-button col-4" onClick={this.handleOpenDialog.bind(this, item._id)}>Read </Button>
{ isAuthenticated === true && (item.blog_by === user._id) ?
<span className="col=8">
<Button className="remove-btn-blog-post"
color="danger"
size="sm"
onClick= {this.onDeleteBlogClick.bind(this, item._id)} title="Delete Blog">
×
</Button>
<a className="btn edit-btn-blog-post" href="#"
onClick={this.replaceModalItem.bind(this, item._id, item.blog_short_desc, item.blog_name, item.blog_desc, item.blog_image_link, item.blog_by, item.blog_by_author )} title="Edit Blog">
<i className="fa fa-pencil" aria-hidden="true"></i>
</a>
</span> : null }
</p>
<p style={{ fontWeight:'bold'}}>By-{item.blog_by_author} <span style={{float:'right',}}>{Moment(item.date).format('Do MMMM YYYY')}</span></p>
</CardActions>
</Card>
</Cell>
))}
</Grid>
</div>
)}
<Pagination
activePage={this.state.activePage}
itemsCountPerPage={6}
totalItemsCount={blogs.length}
pageRangeDisplayed={5}
onChange={this.handlePageChange.bind(this)}
itemClass='page-item'
linkClass='page-link'
/>
</Container>
)
}
}
const mapStateToProps = (state) => ({
resume: state.resume,
auth: state.auth,
loading: state.apiCallsInProgress > 0
});
export default connect(mapStateToProps, {getBlog, deleteBlog, updateBlog }) (Blogs);
//Edit.js
const EditBlog = ({ toggle, onTodoChange, onSubmit, ...state}) => {
return(
<span>
<Modal
isOpen = {state.modal && state.requiredItem === state._id}
toggle = {()=>this.toggle(state._id)}
>
<ModalHeader toggle={toggle} style={{fontWeight: "bold"}}>
Edit your blog {state.blog_name}
</ModalHeader>
<ModalBody>
<Form onSubmit={e => onSubmit(e, state._id )}>
<FormGroup>
<Label for="blogHeading">Blog Heading</Label>
<Input type="text" name="blog_short_desc" id="blogHeading" placeholder="Update one liner"
onChange={onTodoChange} defaultValue={state.blog_short_desc}/>
<Label for="blogName">Blog Name</Label>
<Input type="text" name="blog_name" id="blogName" placeholder="Update blog name"
onChange={onTodoChange} defaultValue={state.blog_name}/>
<Label for="desc1">Description </Label>
<Input type="textarea" name="blog_desc" id="desc1" placeholder="Update your blog"
onChange={onTodoChange} defaultValue={state.blog_desc}/>
<Label for="imageUrl">Image Url</Label>
<Input type="text" name="blog_image_link" id="imageUrl" placeholder="Update image url (Optional)"
onChange={onTodoChange} defaultValue={state.blog_image_link}/>
<Button
color="dark"
style={{marginTop: '2rem'}}
block
>Edit blog</Button>
</FormGroup>
</Form>
</ModalBody>
</Modal>
</span>
)
}
const mapStateToProps = state => ({
resume: state.resume,
auth: state.auth
})
export default connect(mapStateToProps, { updateBlog })(EditBlog);
// Current UI of working edit
onTodoChange
関数が親Blogs
コンポーネントの状態を設定しているように見えますが、その状態では入力値に戻りません。代わりに、親はblogs
プロップをEditBlogs
に渡します。onTodoChange
はblogs
に影響しないため、入力のvalue
は変更されません。
これは、入力のonChange
イベント値(e.target.value
)入力のvalue
属性に戻さないでください。そのため、入力が実際に値を変更することはありません。
blog_
state
とonTodoChange
の値はすべて編集フォームに対してローカルなので、それらをそのレベルまで下げることをお勧めします。Blogs
はそのことについて知る必要はありません、そしてそれは物事を簡素化します-onTodoChange
はイベント値をstate
に設定し、それは値として入力に直接戻ります。
blogs
プロップは、初期state
のみを設定する必要があります。
ユーザーがブログを編集しているときに、ブログの情報を取得して、このようなオブジェクトを作成します
userBlogData={
blog_heading: 'users blog heading',
blog_name: 'users blog name',
description: 'users blog description',
image_url: 'users blog image url',
}
これらのオブジェクトに基づいてモーダルフォームを更新します。例えば:
<input name="blog_heading" value={blog_heading} ... />
ユーザーがオブジェクトを編集した後、サーバーで更新リクエストを作成し、同時にget関数を呼び出してブログを更新できます。編集コンポーネントの更新機能を保持できます。しかし、get関数は小道具として渡されます。
お役に立てれば
これはあなたにアイデアを与えるはずです...........................
// Edit Component
this.state = {
blog_name:this.props.data.blog_name
}
onBlogUpdate = () => {
let payload = this.state
API CALL...
}
...
render(){
return(
<input value={this.state.blog_name} name='blog_name' onChange={...} ... />
)
}