From 548277bb5100d7a4da3a9753769d44eb4c5c26e6 Mon Sep 17 00:00:00 2001 From: raychanks <34273644+raychanks@users.noreply.github.com> Date: Thu, 13 Jan 2022 00:34:00 +0800 Subject: [PATCH] fix: defer change update for number input (#291) --- addons/ondevice-controls/src/PropForm.tsx | 10 ++++-- addons/ondevice-controls/src/types/Number.tsx | 33 ++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/addons/ondevice-controls/src/PropForm.tsx b/addons/ondevice-controls/src/PropForm.tsx index 7f20258e1d..a808e9c915 100644 --- a/addons/ondevice-controls/src/PropForm.tsx +++ b/addons/ondevice-controls/src/PropForm.tsx @@ -1,5 +1,7 @@ -import React from 'react'; +import React, { memo } from 'react'; import { View } from 'react-native'; +import deepEqual from 'deep-equal'; + import { ArgTypes } from './ControlsPanel'; import PropField from './PropField'; @@ -25,4 +27,8 @@ const PropForm = ({ args, onFieldChange }: FormProps) => { ); }; -export default PropForm; +const deepStrictEqual = (a: any, b: any): boolean => { + return deepEqual(a, b, { strict: true }); +}; + +export default memo(PropForm, deepStrictEqual); diff --git a/addons/ondevice-controls/src/types/Number.tsx b/addons/ondevice-controls/src/types/Number.tsx index 39744a767e..8a8e96e09d 100644 --- a/addons/ondevice-controls/src/types/Number.tsx +++ b/addons/ondevice-controls/src/types/Number.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { StyleSheet, View } from 'react-native'; import Slider from '@react-native-community/slider'; import styled from '@emotion/native'; @@ -26,18 +26,35 @@ export interface NumberProps { onChange: (value: any) => void; } +const replaceComma = (value: number | string): string => { + return typeof value === 'string' ? value.trim().replace(/,/, '.') : value.toString(); +}; + const NumberType = ({ arg, onChange = (value) => value }: NumberProps) => { - const allowComma = typeof arg.value === 'string' ? arg.value.trim().replace(/,/, '.') : arg.value; - const showError = Number.isNaN(Number(allowComma)); + const allowComma = replaceComma(arg.value); + const [numStr, setNumStr] = useState(allowComma); + const numStrRef = useRef(numStr); + const showError = Number.isNaN(Number(numStr)); + + const commitChange = () => { + onChange(numStr); + }; const renderNormal = () => { return ( { + const commaReplaced = replaceComma(text); + + setNumStr(commaReplaced); + numStrRef.current = commaReplaced; + }} + onSubmitEditing={commitChange} + onEndEditing={commitChange} style={showError && styles.errorBorder} /> ); @@ -55,6 +72,12 @@ const NumberType = ({ arg, onChange = (value) => value }: NumberProps) => { ); }; + useEffect(() => { + return () => { + onChange(numStrRef.current); + }; + }, [onChange]); + return {arg.range ? renderRange() : renderNormal()}; };