javascript - 如何使用 ReactJs 将 Props() 值传递到 setState() 以使模态表单可编辑

标签 javascript reactjs redux react-hooks react-state

我正在创建我的博客用户可以在其中编辑他/她的博客。 在这里,我将数据弹出到模态中以进行编辑..

经过所有调试和更好的思考,我已经解决了这个问题。这是我更新的 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">
                                                &times;
                                            </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);

//编辑.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);

//当前工作edit的UI

enter image description here

最佳答案

首先,不可编辑的错误是由于在“defaultValue”内的模态中使用“value” Prop 引起的。如果你使用值(value),你总是赋予它初始 Prop 的值(value)。使用默认值。使用 defaultValue 使其成为受控组件。了解更多 Stackoverflow here 。更改它并查看下一个问题(如果有)。

其次,确保避免 UNSAFE_componentWillReceiveProps() 。查看您的 componentWillRecieveProps 方法,文档中所说的内容可能会起作用:

“调用 this.setState() 通常不会触发 UNSAFE_componentWillReceiveProps()。”

更新:

删除 componentWillReceiveProps 方法。提交应该有效。并确保用户经过身份验证。

关于javascript - 如何使用 ReactJs 将 Props() 值传递到 setState() 以使模态表单可编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61412045/

相关文章:

javascript - 在 react : the react way 中将函数传递给 child

javascript - 渲染数据前添加条件和排序

javascript - 重新渲染时组件崩溃 | react 、Redux

javascript - 在 React-Redux 中访问输入字段的正确方法是什么?

javascript - 让 iframe 点击,但不是 iframe 的主体

javascript - 如何在 View 中包含 js 文件。 ASP.NET MVC 4

reactjs - react / typescript : Consuming context via HOC

javascript - 清除页面部分

javascript - 如何为 html 幻灯片创建一个升序的文本/数字序列

testing - Chai 的 Redux 测试问题