[英]How to pass Props() value into setState() to make modal form editable using ReactJs
I am creating my blog
where an user
can able to edit
his/her blogs.我正在创建我的
blog
, user
可以在其中edit
他/她的博客。 Here I am popping the data into a modal to make this edit
..在这里,我将数据弹出到模态中以进行此
edit
..
So after all debugging and a better thinking I have figure this out.所以在调试和更好的思考之后我已经弄清楚了。 This is my updated working code for
modal
这是我更新的
modal
工作代码
Thank you for your time.感谢您的时间。
//blog.js //博客.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 //编辑.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);
//CurrentUI of working edit
//工作
edit
的当前UI
First, the uneditable bug is caused by using "value" props for your input in modal inside of "defaultValue".首先,不可编辑的错误是由于在“defaultValue”内的模态中使用“value”道具输入造成的。 If you use value, you are always giving it the value of initial props.
如果你使用价值,你总是给它初始道具的价值。 Use default value.
使用默认值。 Using defaultValue makes it a controlled component.
使用 defaultValue 使其成为受控组件。 Read more on Stackoverflow here .
在此处阅读有关 Stackoverflow 的更多信息。 Change that and see next issues if any.
更改它并查看下一个问题(如果有)。
Second, ensure you avoid UNSAFE_componentWillReceiveProps() .其次,确保避免使用 UNSAFE_componentWillReceiveProps() 。 Looking at your componentWillRecieveProps method, what is said in the documentation may be at play:
查看您的 componentWillRecieveProps 方法,文档中所说的可能在起作用:
"Calling this.setState() generally doesn't trigger UNSAFE_componentWillReceiveProps()." “调用 this.setState() 通常不会触发 UNSAFE_componentWillReceiveProps()。”
Update:更新:
Remove the componentWillReceiveProps method.删除 componentWillReceiveProps 方法。 submit should work.
提交应该工作。 And ensure user is authenticated.
并确保用户已通过身份验证。
It looks to me like your onTodoChange
function is setting state on the parent Blogs
component, but that state doesn't make it back to the input values.在我看来,您的
onTodoChange
function 正在父Blogs
组件上设置 state,但 state 不会返回输入值。 Instead, the parent passes a blogs
prop into EditBlogs
, and since onTodoChange
never affects blogs
, the input's value
remains unchanged.相反,父级将
blogs
属性传递给EditBlogs
,并且由于onTodoChange
从不影响blogs
,因此输入的value
保持不变。
This means your inputs' onChange
event values ( e.target.value
) never make it back to the inputs' value
attribute, so the input doesn't actually change values.这意味着您输入的
onChange
事件值 ( e.target.value
) 永远不会返回输入的value
属性,因此输入实际上不会更改值。
Since the blog_
values in state
and onTodoChange
are all local to the edit form, I recommend moving those down to that level.. Blogs
doesn't need to know about that stuff, and it'll simplify things - onTodoChange
will set event values into state
, which will flow right back into the inputs as values.由于
state
和onTodoChange
中的blog_
值都是编辑表单的本地值,我建议将它们向下移动到那个级别。 Blogs
不需要知道这些东西,它会简化事情 - onTodoChange
会将事件值设置为state
,它将作为值流回输入。
Your blogs
prop should only set the initial state
.你的
blogs
道具应该只设置初始的state
。
When a user is editing their blog, take their blog information and create an object like this当一个用户在编辑他们的博客时,拿他们的博客信息并创建一个 object 像这样
userBlogData={
blog_heading: 'users blog heading',
blog_name: 'users blog name',
description: 'users blog description',
image_url: 'users blog image url',
}
Update the modal form based on these objects.根据这些对象更新模态形式。 For example:
例如:
<input name="blog_heading" value={blog_heading} ... />
After the user have edited the object you can make an update request on your server and call the get function at the same time for updating the blogs.用户编辑完 object 后,您可以在您的服务器上发出更新请求,同时调用 get function 来更新博客。 You can keep the update function on the edit component.
您可以在编辑组件上保留更新 function。 But the get function will be passed as a props.
但是 get function 将作为道具传递。
Hope This Helps希望这可以帮助
This should give you the idea...........................这应该给你的想法......................................
// 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={...} ... />
)
}
I have figure it out with我已经弄明白了
OnClick
of edit
button I passed all required data along with it. edit
按钮的OnClick
我传递了所有必需的数据。 So, my replaceModalItem()
binds all data together in setState()
所以,我的
replaceModalItem()
在setState()
中将所有数据绑定在一起
In replaceModalItem
i called those data and set it to setState()
.在
replaceModalItem
,我调用了这些数据并将其设置为setState()
。
In Edit.js
I have called all the state
values.在
Edit.js
,我调用了所有state
值。
Hence getting all the required values in input field setting it with defaultValue
因此在输入字段中获取所有必需的值并将其设置为
defaultValue
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.