From 90a71f962702f7702b07a7bc27e822b6595fd52a Mon Sep 17 00:00:00 2001 From: Gabriel Dutra Date: Wed, 15 May 2019 21:55:07 -0300 Subject: [PATCH 1/3] Call onSelect only after state is set --- client/app/components/DateTimeInput.jsx | 89 +++++++++++++------------ 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/client/app/components/DateTimeInput.jsx b/client/app/components/DateTimeInput.jsx index 2898233ca2..a2a96c8a42 100644 --- a/client/app/components/DateTimeInput.jsx +++ b/client/app/components/DateTimeInput.jsx @@ -1,55 +1,58 @@ -import React, { useState } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { react2angular } from 'react2angular'; import DatePicker from 'antd/lib/date-picker'; import { clientConfig } from '@/services/auth'; import { Moment } from '@/components/proptypes'; -export function DateTimeInput({ - value, - withSeconds, - onSelect, - className, -}) { - const format = (clientConfig.dateFormat || 'YYYY-MM-DD') + - (withSeconds ? ' HH:mm:ss' : ' HH:mm'); - let defaultValue; - if (value && value.isValid()) { - defaultValue = value; +export class DateTimeInput extends React.Component { + static propTypes = { + value: Moment, + withSeconds: PropTypes.bool, + onSelect: PropTypes.func, + className: PropTypes.string, + }; + + static defaultProps = { + value: null, + withSeconds: false, + onSelect: () => {}, + className: '', + }; + + constructor(props) { + super(props); + const { value } = props; + this.state = { currentValue: value && value.isValid() ? value : null, open: false }; } - const [currentValue, setCurrentValue] = useState(defaultValue); - return ( - setCurrentValue(newValue)} - onOpenChange={(status) => { - if (!status) { // on close picker - if (currentValue && currentValue.isValid()) { - onSelect(currentValue); - } - } - }} - /> - ); -} -DateTimeInput.propTypes = { - value: Moment, - withSeconds: PropTypes.bool, - onSelect: PropTypes.func, - className: PropTypes.string, -}; + render() { + const { withSeconds, onSelect, className } = this.props; + const format = (clientConfig.dateFormat || 'YYYY-MM-DD') + + (withSeconds ? ' HH:mm:ss' : ' HH:mm'); -DateTimeInput.defaultProps = { - value: null, - withSeconds: false, - onSelect: () => {}, - className: '', -}; + return ( + this.setState({ currentValue: newValue })} + onOpenChange={(status) => { + this.setState({ open: status }, () => { + const { open, currentValue } = this.state; + if (!open) { // on close picker + if (currentValue && currentValue.isValid()) { + onSelect(currentValue); + } + } + }); + }} + /> + ); + } +} export default function init(ngModule) { ngModule.component('dateTimeInput', react2angular(DateTimeInput)); From 02b668e9daecfe8a613465c0ae73b1ef96f2498d Mon Sep 17 00:00:00 2001 From: Gabriel Dutra Date: Thu, 16 May 2019 07:29:06 -0300 Subject: [PATCH 2/3] Revert "Call onSelect only after state is set" This reverts commit 90a71f962702f7702b07a7bc27e822b6595fd52a. --- client/app/components/DateTimeInput.jsx | 89 ++++++++++++------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/client/app/components/DateTimeInput.jsx b/client/app/components/DateTimeInput.jsx index a2a96c8a42..2898233ca2 100644 --- a/client/app/components/DateTimeInput.jsx +++ b/client/app/components/DateTimeInput.jsx @@ -1,58 +1,55 @@ -import React from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { react2angular } from 'react2angular'; import DatePicker from 'antd/lib/date-picker'; import { clientConfig } from '@/services/auth'; import { Moment } from '@/components/proptypes'; -export class DateTimeInput extends React.Component { - static propTypes = { - value: Moment, - withSeconds: PropTypes.bool, - onSelect: PropTypes.func, - className: PropTypes.string, - }; - - static defaultProps = { - value: null, - withSeconds: false, - onSelect: () => {}, - className: '', - }; - - constructor(props) { - super(props); - const { value } = props; - this.state = { currentValue: value && value.isValid() ? value : null, open: false }; +export function DateTimeInput({ + value, + withSeconds, + onSelect, + className, +}) { + const format = (clientConfig.dateFormat || 'YYYY-MM-DD') + + (withSeconds ? ' HH:mm:ss' : ' HH:mm'); + let defaultValue; + if (value && value.isValid()) { + defaultValue = value; } + const [currentValue, setCurrentValue] = useState(defaultValue); + return ( + setCurrentValue(newValue)} + onOpenChange={(status) => { + if (!status) { // on close picker + if (currentValue && currentValue.isValid()) { + onSelect(currentValue); + } + } + }} + /> + ); +} - render() { - const { withSeconds, onSelect, className } = this.props; - const format = (clientConfig.dateFormat || 'YYYY-MM-DD') + - (withSeconds ? ' HH:mm:ss' : ' HH:mm'); +DateTimeInput.propTypes = { + value: Moment, + withSeconds: PropTypes.bool, + onSelect: PropTypes.func, + className: PropTypes.string, +}; - return ( - this.setState({ currentValue: newValue })} - onOpenChange={(status) => { - this.setState({ open: status }, () => { - const { open, currentValue } = this.state; - if (!open) { // on close picker - if (currentValue && currentValue.isValid()) { - onSelect(currentValue); - } - } - }); - }} - /> - ); - } -} +DateTimeInput.defaultProps = { + value: null, + withSeconds: false, + onSelect: () => {}, + className: '', +}; export default function init(ngModule) { ngModule.component('dateTimeInput', react2angular(DateTimeInput)); From 4d72ea2e03046a93b776d4e24545cefb5235e497 Mon Sep 17 00:00:00 2001 From: Gabriel Dutra Date: Thu, 16 May 2019 08:24:53 -0300 Subject: [PATCH 3/3] Use useRef instead of useState for DateTime inputs --- client/app/components/DateTimeInput.jsx | 13 +++++++------ client/app/components/DateTimeRangeInput.jsx | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/client/app/components/DateTimeInput.jsx b/client/app/components/DateTimeInput.jsx index 2898233ca2..7f185fef0b 100644 --- a/client/app/components/DateTimeInput.jsx +++ b/client/app/components/DateTimeInput.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useRef } from 'react'; import PropTypes from 'prop-types'; import { react2angular } from 'react2angular'; import DatePicker from 'antd/lib/date-picker'; @@ -13,20 +13,21 @@ export function DateTimeInput({ }) { const format = (clientConfig.dateFormat || 'YYYY-MM-DD') + (withSeconds ? ' HH:mm:ss' : ' HH:mm'); - let defaultValue; + const additionalAttributes = {}; if (value && value.isValid()) { - defaultValue = value; + additionalAttributes.defaultValue = value; } - const [currentValue, setCurrentValue] = useState(defaultValue); + const currentValueRef = useRef(additionalAttributes.defaultValue); return ( setCurrentValue(newValue)} + onChange={(newValue) => { currentValueRef.current = newValue; }} onOpenChange={(status) => { + const currentValue = currentValueRef.current; if (!status) { // on close picker if (currentValue && currentValue.isValid()) { onSelect(currentValue); diff --git a/client/app/components/DateTimeRangeInput.jsx b/client/app/components/DateTimeRangeInput.jsx index 625f46f35f..d6c17ab130 100644 --- a/client/app/components/DateTimeRangeInput.jsx +++ b/client/app/components/DateTimeRangeInput.jsx @@ -1,5 +1,5 @@ import { isArray } from 'lodash'; -import React, { useState } from 'react'; +import React, { useRef } from 'react'; import PropTypes from 'prop-types'; import { react2angular } from 'react2angular'; import DatePicker from 'antd/lib/date-picker'; @@ -16,19 +16,20 @@ export function DateTimeRangeInput({ }) { const format = (clientConfig.dateFormat || 'YYYY-MM-DD') + (withSeconds ? ' HH:mm:ss' : ' HH:mm'); - let defaultValue; + const additionalAttributes = {}; if (isArray(value) && value[0].isValid() && value[1].isValid()) { - defaultValue = value; + additionalAttributes.defaultValue = value; } - const [currentValue, setCurrentValue] = useState(defaultValue); + const currentValueRef = useRef(additionalAttributes.defaultValue); return ( setCurrentValue(newValue)} + onChange={(newValue) => { currentValueRef.current = newValue; }} onOpenChange={(status) => { + const currentValue = currentValueRef.current; if (!status) { // on close picker if (isArray(currentValue) && currentValue[0].isValid() && currentValue[1].isValid()) { onSelect(currentValue);