Обновление состояния с помощью Reactjs DatePicker не работает - PullRequest
0 голосов
/ 19 октября 2018

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

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

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

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

  • UncaughtTypeError: Невозможно прочитать свойство 'value' из неопределенного

, и ввод пуст, не отображает сегодняшнюю дату, как предполагалось, пример здесь: enter image description here

Вот мой компонент 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.log('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;

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

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Даты, приходящие из вашей выборки, должны быть конвертированы в Момент дату.Я не знаю, в каком формате возвращается ваша дата, но если она не в формате 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, предоставленный компонентом, возвращает выбранную дату (это не похоже на обработчик события normal *1007* JS).Поэтому вы не получите объект, у которого есть event.target.value.Вместо этого вы получите выбранную дату, поэтому просто установите значение параметра startDate в вашем объекте состояния:

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

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

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

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

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

this.state = {
        projectname: '',
        typeofproject: 'Film (Cinema)', //if you want a default selected otherwise leave as empty string
        imageURL: '',
        startDate: moment(),
        endDate: moment()
    }  
0 голосов
/ 20 октября 2018

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

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

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

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

...