Как передать значение Props () в setState (), чтобы сделать модальную форму редактируемой, используя ReactJs - PullRequest
4 голосов
/ 24 апреля 2020

Я создаю свой 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">
                                                &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);

// CurrentUI работающих edit

enter image description here

Ответы [ 4 ]

2 голосов
/ 26 апреля 2020

Во-первых, нередактируемая ошибка вызвана использованием реквизитов «значения» для вашего ввода в модальном внутри «defaultValue». Если вы используете значение, вы всегда даете ему значение начального реквизита. Используйте значение по умолчанию. Использование defaultValue делает его контролируемым компонентом. Подробнее о Stackoverflow здесь . Измените это и посмотрите следующие проблемы, если таковые имеются.

Во-вторых, убедитесь, что вы избегаете UNSAFE_componentWillReceiveProps () . Глядя на ваш метод componentWillRecieveProps, можно сказать, что сказано в документации:

"Вызов this.setState () обычно не вызывает UNSAFE_componentWillReceiveProps ()."

Обновление:

Удалите метод componentWillReceiveProps. отправить должен работать. И убедитесь, что пользователь аутентифицирован.

1 голос
/ 27 апреля 2020

Я понял это с помощью кнопки

  1. OnClick из edit Я передал все необходимые данные вместе с ней. Итак, мой replaceModalItem() связывает все данные вместе в setState()

  2. В replaceModalItem я вызвал эти данные и установил их на setState().

  3. В Edit.js Я вызвал все значения state.

Следовательно, получая все необходимые значения в поле ввода, установив его с помощью defaultValue

enter image description here

1 голос
/ 26 апреля 2020

Когда пользователь редактирует свой блог, возьмите информацию о своем блоге и создайте подобный объект

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={...} ... />
        )
     }
1 голос
/ 25 апреля 2020

Мне кажется, что ваша функция onTodoChange устанавливает состояние родительского компонента Blogs, но это состояние не возвращает его к входным значениям. Вместо этого родительский элемент передает blogs реквизит в EditBlogs, и поскольку onTodoChange никогда не влияет на blogs, value входных данных остается неизменным.

Это означает, что значения событий ваших входных данных onChange (e.target.value) никогда не вернется к атрибуту value входов, поэтому входные данные фактически не изменяют значения.

Поскольку значения blog_ в state и onTodoChange все локально к форме редактирования, я рекомендую переместить их на этот уровень .. Blogs не нужно знать об этом, и это упростит вещи - onTodoChange установит значения событий в state, что вернитесь обратно к входам как значениям.

Ваша blogs опора должна устанавливать только начальную state.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...