From e9aff5cec2f54d37c25e7779a722909bcd7e95a6 Mon Sep 17 00:00:00 2001 From: suanmei Date: Thu, 14 May 2020 19:06:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20field=20=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=E5=90=8E=E6=97=A0=E6=B3=95=E8=BF=9E=E8=B4=AF=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=E5=B1=9E=E6=80=A7=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/field-input.tsx | 33 +++++++++++++++---- .../src/components/layout.tsx | 4 +-- .../src/components/schema-form.tsx | 5 +-- .../src/components/schema-head.tsx | 4 +-- .../src/components/schema-item.tsx | 29 ++++------------ .../json-schema-editor/src/reducer/schema.ts | 23 +++++++++---- 6 files changed, 56 insertions(+), 42 deletions(-) diff --git a/packages/json-schema-editor/src/components/field-input.tsx b/packages/json-schema-editor/src/components/field-input.tsx index 4e6b9b6..8e106bc 100644 --- a/packages/json-schema-editor/src/components/field-input.tsx +++ b/packages/json-schema-editor/src/components/field-input.tsx @@ -1,11 +1,13 @@ import * as React from 'react'; import styled from '@emotion/styled'; -import { Input } from 'antd'; +import { Tooltip, Input, Checkbox } from 'antd'; +import { useTranslation } from 'react-i18next'; interface FieldInputProps { value: string; + required: boolean; changeField: (value: string) => void; - addonAfter: JSX.Element; + toggleRequired: (value: string) => void; } const CustomInput = styled(Input)` @@ -15,9 +17,18 @@ const CustomInput = styled(Input)` } `; -function FieldInput(props: FieldInputProps, ref: React.Ref): JSX.Element { - const { value: initValue, changeField, addonAfter } = props; +function FieldInput(props: FieldInputProps): JSX.Element { + const { value: initValue, changeField, required, toggleRequired } = props; const [value, setValue] = React.useState(initValue); + const [prevInitValue, setPrevInitValue] = React.useState(initValue); + + const { t } = useTranslation(); + + // mock getDerivedStateFromProps + if (initValue !== prevInitValue) { + setValue(initValue); + setPrevInitValue(initValue); + } const handleChange = (e: React.ChangeEvent): void => { setValue(e.target.value); @@ -38,14 +49,22 @@ function FieldInput(props: FieldInputProps, ref: React.Ref): JSX.Element return ( + { + toggleRequired(value); + }} + /> + + } /> ); } -export default React.forwardRef(FieldInput); +export default React.memo(FieldInput); diff --git a/packages/json-schema-editor/src/components/layout.tsx b/packages/json-schema-editor/src/components/layout.tsx index 5d42109..cb16e1e 100644 --- a/packages/json-schema-editor/src/components/layout.tsx +++ b/packages/json-schema-editor/src/components/layout.tsx @@ -11,11 +11,11 @@ import { SchemaState } from '../model'; let temp: SchemaState | null = null; -interface AA { +interface LayoutProps { onChange: (value: SchemaState) => void; } -function Layout({ onChange }: AA): JSX.Element { +function Layout({ onChange }: LayoutProps): JSX.Element { const { t } = useTranslation(); const uiState = useUIState(); diff --git a/packages/json-schema-editor/src/components/schema-form.tsx b/packages/json-schema-editor/src/components/schema-form.tsx index d197db9..6f382da 100644 --- a/packages/json-schema-editor/src/components/schema-form.tsx +++ b/packages/json-schema-editor/src/components/schema-form.tsx @@ -14,14 +14,15 @@ function SchemaForm({ data, keyRoute }: SchemaFormProps): JSX.Element { return (
- {Object.keys(properties).map((field) => { + {Object.keys(properties).map((field, index) => { const itemData = properties[field]; const isRequired = required && required.includes(field); const fieldKeyRoute = keyRoute.concat(field); return ( - } /> + } /> - } /> + } /> diff --git a/packages/json-schema-editor/src/components/schema-item.tsx b/packages/json-schema-editor/src/components/schema-item.tsx index 67a260e..b191b72 100644 --- a/packages/json-schema-editor/src/components/schema-item.tsx +++ b/packages/json-schema-editor/src/components/schema-item.tsx @@ -1,7 +1,6 @@ /** @jsx jsx */ -import { useRef } from 'react'; import { jsx } from '@emotion/core'; -import { Row, Col, Tooltip, Input, Checkbox, Select } from 'antd'; +import { Row, Col, Tooltip, Input, Select } from 'antd'; import { useTranslation } from 'react-i18next'; import { useUIState, useSetUIState } from '../store/ui'; import { useSchemaDispatch } from '../store/schema'; @@ -28,15 +27,8 @@ interface SchemaItemProps { children: React.ReactChild | null; } -function SchemaFormItem({ - field, - data, - required, - keyRoute, - children, -}: SchemaItemProps): JSX.Element { - const fieldRef = useRef(null); - +function SchemaFormItem(props: SchemaItemProps): JSX.Element { + const { field, data, required, keyRoute, children } = props; const { t } = useTranslation(); const schemaDispatch = useSchemaDispatch(); const setUIState = useSetUIState(); @@ -48,11 +40,8 @@ function SchemaFormItem({ setUIState((prev) => ({ ...prev, [key]: !visible })); }; - const toggleRequired = (): void => { - if (!fieldRef.current) return; - - const newField = fieldRef.current.state.value; - const fieldKeyRoute = keyRoute.slice(0, -1).concat(newField); + const toggleRequired = (value: string): void => { + const fieldKeyRoute = keyRoute.slice(0, -1).concat(value); if (required) { schemaDispatch({ type: 'REMOVE_REQUIRED', keyRoute: fieldKeyRoute }); @@ -100,14 +89,10 @@ function SchemaFormItem({ - - - } + toggleRequired={toggleRequired} /> diff --git a/packages/json-schema-editor/src/reducer/schema.ts b/packages/json-schema-editor/src/reducer/schema.ts index ab9409f..e14118b 100644 --- a/packages/json-schema-editor/src/reducer/schema.ts +++ b/packages/json-schema-editor/src/reducer/schema.ts @@ -1,5 +1,5 @@ import produce, { Draft } from 'immer'; -import { get, set, unset, remove, cloneDeep } from 'lodash-es'; +import { get, set, unset, remove } from 'lodash-es'; import { SchemaType, SchemaItem, SchemaState, SchemaAction, KeyRoute } from '../model'; import { defaultSchema, setAllFieldRequired } from '../utils/schema'; @@ -25,6 +25,19 @@ const removeRequired = (state: SchemaState, keyRoute: KeyRoute): void => { set(state, requiredKeyRoute, required); }; +const changeRequiredField = (state: SchemaState, oldKeyRoute: KeyRoute, newField: string): void => { + const oldField = oldKeyRoute.slice(-1)[0]; + const requiredKeyRoute = oldKeyRoute.slice(0, -2).concat('required'); + const required = get(state, requiredKeyRoute) || []; + const oldFieldIndex = required.indexOf(oldField); + + // new field extend the old field + if (oldFieldIndex > -1) { + required.splice(oldFieldIndex, 1, newField); + set(state, requiredKeyRoute, required); + } +}; + const toggleAllChecked = (state: SchemaState, checked: boolean): void => { setAllFieldRequired(state, checked); }; @@ -82,12 +95,8 @@ const changeField = (state: SchemaState, keyRoute: KeyRoute, newField: string): set(state, parentKeyRoute, newProperties); - // remove old filed from its parent's required - removeRequired(state, keyRoute); - - // add new filed to its parent's required - const fieldKeyRoute = parentKeyRoute.concat(newField); - addRequired(state, fieldKeyRoute); + // replace old field with new field in required + changeRequiredField(state, keyRoute, newField); }; const changeType = (state: SchemaState, keyRoute: KeyRoute, fieldType: SchemaType): void => {