Состояние обновления с помощью Reactjs DatePicker не работает

Я добавляю проекты с помощью datepicker, и он работает, но когда я пытаюсь редактировать / обновлять эти проекты с помощью datepicker, не работает! дайте мне много ошибок, таких как:

  • Неудачный тип опоры: недопустимая опора selected типа string, предоставленная для DatePicker, ожидаемая object

  • Компонент изменяет неконтролируемый ввод контролируемого текста типа. Элементы ввода не должны переключаться с неконтролируемого на управляемый (или наоборот). Выберите между использованием контролируемого или неконтролируемого элемента ввода на протяжении всего срока службы компонента.

  • Неудачный тип опоры: недопустимая опора selected типа string, предоставленная для Calendar/Month/Week/Day, ожидаемая object.

  • Uncaught TypeError: невозможно прочитать значение свойства undefined

и ввод пуст, не показывает сегодняшнюю дату, как предполагалось, пример здесь: Состояние обновления с помощью Reactjs DatePicker не работает

Вот мой компонент EditProject:

import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import DatePicker from 'react-datepicker';
import moment from 'moment';

import './EditProject.css';
import 'react-datepicker/dist/react-datepicker.css';


class EditProject extends Component {
    constructor(props) {
        super(props);
        this.state = {
            project: {}
        }    
    }

    componentDidMount() {

        // console.info('PROPS ' + JSON.stringify(this.props));

        const { match: { params } } = this.props;


        fetch(`/dashboard/project/${params.id}/edit`)
            .then(response => {
                return response.json()
            }).then(project => {
                this.setState({
                    projectname: project.projectname,
                    typeofproject: project.typeofproject,
                    imageURL: project.imageURL,
                    startDate: project.startDate,
                    endDate: project.endDate
                })
            })
    }

    render() {
        const { match: { params } } = this.props;

        return (
            <div className='EditProject'>
                <h1 className='EditProject__title'>Edit</h1><h1 className='EditProject__projectname'>{this.state.projectname}</h1>
                <hr />
                <form method='POST' action = {`/dashboard/project/${params.id}/edit?_method=PUT`}>
                    <div className='form-group container'>
                        <div className = "input-group mb-3">
                            <div className = "input-group-prepend">
                                <span className = "input-group-text" style = {{border:'none'}} id = "basic-addon1">Project Name</span>
                            </div>
                            <input type='text' className='form-control input' placeholder='insert new project name' value = {this.state.projectname} name='projectname' ref='projectname' onChange = {(event) => this.setState({ projectname: event.target.value })} />
                        </div>
                    </div>
                    <div className='form-group container'>
                        <div className = "input-group mb-3">
                            <div className = "input-group-prepend">
                                <span className = "input-group-text" style = {{border:'none'}} id = "basic-addon1">Type of Production</span>
                            </div>
                            <select className='form-control input' value = {this.state.typeofproject} name='typeofproject' ref='typeofproject' onChange = {(event) => this.setState({ typeofproject: event.target.value })}>
                                <option value='Film (Cinema)'>Film (Cinema)</option>
                                <option value='Film (TV)'>Film (TV)</option>
                                <option value='Film (series)'>Film (series)</option>
                                <option value='Short film'>Short film</option>
                                <option value='TV mini-series'>TV mini-series</option>
                                <option value='TV series'>TV series</option>
                                <option value='TV program'>TV program</option>
                                <option value='TV reporting'>TV reporting</option>
                                <option value='Vox Pop'>Vox Pop</option>
                                <option value='Advertisement Ad'>Advertisement Ad</option>
                                <option value='Documentary'>Documentary</option>
                                <option value='Documentary (TV)'>Documentary (TV)</option>
                                <option value='Documentary (series)'>Documentary (series)</option>
                                <option value='Commercial'>Commercial</option>
                                <option value='Video Clip'>Video Clip</option>
                                <option value='Live Video Clip TV'>Live Video Clip TV</option>
                                <option value='Photography Session'>Photography Session</option>
                            </select>
                        </div>
                    </div>
                    <div className='form-group container'>
                    <div className = "input-group mb-3">
                        <div className = "input-group-prepend">
                            <span className = "input-group-text" style = {{border:'none'}} id = "basic-addon1">Start Date</span>
                        </div>
   // ================DATEPICKER HERE================
                        <DatePicker 
                            todayButton = {"Today"}
                            dateFormat = "DD/MM/YYYY"
                            selected = {this.state.startDate}
                            value = {this.state.startDate}
                            onChange = {(event) => this.setState({ startDate: event.target.value })}
                        />
                    </div>
                </div>
                <div className='form-group container'>
                    <div className = "input-group mb-3">
                        <div className = "input-group-prepend">
                            <span className = "input-group-text" style = {{border:'none'}} id = "basic-addon1">End Date</span>
                        </div>
                        <DatePicker
                            todayButton = {"Today"}
                            dateFormat = "DD/MM/YYYY"
                            selected = {this.state.endDate}
                            value = {this.state.endDate} 
                            onChange = {(event) => this.setState({ endDate: event.target.value })}
                        />
                    </div>
                </div>
   // / ================DATEPICKER HERE================
                    <div className='form-group container'>
                        <div className = "input-group mb-3">
                            <div className = "input-group-prepend">
                                <span className = "input-group-text" style = {{border:'none'}} id = "basic-addon1">Project Image URL</span>
                            </div>
                            <input type='text' className='form-control input 'placeholder='insert new project image URL' value = {this.state.imageURL} name='imageURL' ref='imageURL' onChange = {(event) => this.setState({ imageURL: event.target.value })} />
                        </div>
                    </div>                  
                    <div className='form-group container'>
                        <button type='submit' className='btn btn-default button--update'>Update</button>
                        <NavLink to = {`/project/${params.id}/`} ><button type='submit' style = {{ backgroundColor: '#b5b5b5' }} className='btn btn-default button--update'>Cancel</button></NavLink>
                    </div>
                </form>
            </div>
        );
    }
} 
export default EditProject;

Спасибо большое за вашу помощь!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
5 166
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Разве для startDate не задана строка? Я предполагаю, что это должен быть объект Date, как говорится в ошибке.

Другая проблема, похоже, заключается в том, что при рендеринге ваши выборка и setState (в componentDidMount) не завершаются.

Попробуйте добавить переменную состояния (например, isLoading), инициализированную значением true, и установите для нее значение false, когда все строки componentDidMount будут выполнены. Теперь проверьте его в рендере и отобразите сообщение «загрузка», если isLoading имеет значение false).

Вам также необходимо позаботиться о ситуации, в которой происходит сбой выборки. В таком случае вы вообще не можете отобразить свой datePicker. Я не уверен, кстати, что эта выборка достаточно хороша. В некоторых случаях при обработке ошибок возникают проблемы. Я всегда использую аксиомы.

Ответ принят как подходящий

Даты, полученные из вашей выборки, необходимо преобразовать в дату Момент. Я не знаю, в каком формате возвращается ваша дата, но если он не в формате ISO 8601 (ГГГГ-ММ-ДД), вам также необходимо указать формат при создании объекта Moment, поэтому измените свой код на один из следующий:

startDate: moment(project.startDate)
startDate: moment(project.startDate, 'DD-MM-YYYY') //specify format that is relevant for your date string if it is not ISO8601

Обработчик события onChange, предоставляемый компонентом, возвращает выбранную дату (это не похоже на обработчик событий обычный JS). Следовательно, вы не получите объект с event.target.value. Вместо этого вы получите выбранную дату, поэтому просто установите значение параметра равным startDate в вашем объекте состояния:

 onChange = {(newDate) => this.setState({ startDate: newDate })}

Обратите внимание, что значение уже будет датой момента, поэтому преобразование не требуется.

Затем вам нужно будет сделать то же самое с endDate и datepicker endDate.

Также обратите внимание, что на самом деле нет необходимости устанавливать свойство value, если вам не нужно изменять то, что на самом деле отображается во входном элементе - обычно вы можете добиться правильного вывода, используя только свойство selected и dateFormat (и, конечно, устанавливая оба значения и selected на то же самое приведет к ошибке, поскольку для первого требуется строка, а для второго - объект момента).

Ошибка в отношении контролируемого к неконтролируемому, вероятно, вызвана тем, что вы не полностью инициализировали свое состояние в своем конструкторе - вы должны инициализировать все свои свойства компонентов чем-то разумным в конструкторе, поскольку ответ на выборку почти наверняка произойдет после первоначального рендеринга, поскольку его на основе обещаний. Ваше начальное состояние в вашем конструкторе должно выглядеть примерно так (кстати, свойство проекта кажется ненужным):

this.state = {
        projectname: '',
        typeofproject: 'Film (Cinema)', //if you want a default selected otherwise leave as empty string
        imageURL: '',
        startDate: moment(),
        endDate: moment()
    }  

Другие вопросы по теме