簡體   English   中英

如何將 Props() 值傳遞給 setState() 以使用 ReactJs 使模態形式可編輯

[英]How to pass Props() value into setState() to make modal form editable using ReactJs

我正在創建我的bloguser可以在其中edit他/她的博客。 在這里,我將數據彈出到模態中以進行此edit ..

所以在調試和更好的思考之后我已經弄清楚了。 這是我更新的modal工作代碼

感謝您的時間。

//博客.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

在此處輸入圖像描述

首先,不可編輯的錯誤是由於在“defaultValue”內的模態中使用“value”道具輸入造成的。 如果你使用價值,你總是給它初始道具的價值。 使用默認值。 使用 defaultValue 使其成為受控組件。 此處閱讀有關 Stackoverflow 的更多信息。 更改它並查看下一個問題(如果有)。

其次,確保避免使用 UNSAFE_componentWillReceiveProps() 查看您的 componentWillRecieveProps 方法,文檔中所說的可能在起作用:

“調用 this.setState() 通常不會觸發 UNSAFE_componentWillReceiveProps()。”

更新:

刪除 componentWillReceiveProps 方法。 提交應該工作。 並確保用戶已通過身份驗證。

在我看來,您的onTodoChange function 正在父Blogs組件上設置 state,但 state 不會返回輸入值。 相反,父級將blogs屬性傳遞給EditBlogs ,並且由於onTodoChange從不影響blogs ,因此輸入的value保持不變。

這意味着您輸入的onChange事件值 ( e.target.value ) 永遠不會返回輸入的value屬性,因此輸入實際上不會更改值。

由於stateonTodoChange中的blog_值都是編輯表單的本地值,我建議將它們向下移動到那個級別。 Blogs不需要知道這些東西,它會簡化事情 - onTodoChange會將事件值設置為state ,它將作為值流回輸入。

你的blogs道具應該只設置初始的state

當一個用戶在編輯他們的博客時,拿他們的博客信息並創建一個 object 像這樣

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} ... />

用戶編輯完 object 后,您可以在您的服務器上發出更新請求,同時調用 get function 來更新博客。 您可以在編輯組件上保留更新 function。 但是 get function 將作為道具傳遞。

希望這可以幫助

這應該給你的想法......................................

    // 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={...} ... />
        )
     }

我已經弄明白了

  1. edit按鈕的OnClick我傳遞了所有必需的數據。 所以,我的replaceModalItem()setState()中將所有數據綁定在一起

  2. replaceModalItem ,我調用了這些數據並將其設置為setState()

  3. Edit.js ,我調用了所有state值。

因此在輸入字段中獲取所有必需的值並將其設置為defaultValue

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM