DouyinFE / semi-design

🚀A modern, comprehensive, flexible design system and React UI library. 🎨 Provide more than 3000+ Design Tokens, easy to build your design system. Make Semi Design to Any Design. 🧑🏻‍💻 Design to Code in one click
https://semi.design
Other
8.42k stars 711 forks source link

[ArrayField] Form's ArrayField through setValue to delete an row data but get null #1745

Open YannLynn opened 1 year ago

YannLynn commented 1 year ago

Is there an existing issue for this?

Which Component

ArrayField

Semi Version

latest

Current Behavior

点击 增加一行,再点击 「change」 删除最后一行数据,FormState 展示为 {"values":{"rules":[{"name":"Semi D2C","role":"Engineer"},{"name":"Semi C2D","role":"Designer"},null]},"errors":{},"touched":{}}

即删除的最后一行数据变为了 null

Expected Behavior

点击 增加一行,再点击 「change」 删除最后一行数据,FormState 展示为 {"values":{"rules":[{"name":"Semi D2C","role":"Engineer"},{"name":"Semi C2D","role":"Designer"}]},"errors":{},"touched":{}}

Steps To Reproduce

将代码粘贴进官网即可复现

ReproducibleCode

class AsyncSetArrayField extends React.Component {
    constructor() {
        super();
        this.state = {
            data: [
                { name: 'Semi D2C', role: 'Engineer' },
                { name: 'Semi C2D', role: 'Designer' },
            ]
        };
        this.getFormApi = this.getFormApi.bind(this); 
        this.change = this.change.bind(this); 
    };
    getFormApi (formApi) {
        this.formApi = formApi;
    }
    change () {
        let rules = this.formApi.getValue('rules'); 
        if (!rules) {
            rules = [];
        }
        rules.splice(rules.length-1, 1);
        console.log('rules', rules);
        this.formApi.setValue('rules', rules);
   }
    render() {
        let { data } = this.state;
        const ComponentUsingFormState = () => {
            const formState = useFormState();
            return (
                <TextArea style={{ marginTop: 10 }} value={JSON.stringify(formState)} />
            );
        };
        return (
            <Form style={{ width: 800 }} labelPosition='left' labelWidth='100px' allowEmpty getFormApi={this.getFormApi}>
                <ArrayField field='rules' initValue={data}>
                    {({ add, arrayFields, addWithInitValue }) => (
                        <React.Fragment>
                            <Button onClick={this.change} theme='light'>change</Button>
                            <Button onClick={add} icon={<IconPlusCircle />} theme='light'>Add new line</Button>
                            <Button icon={<IconPlusCircle />} onClick={() => {addWithInitValue({ name: 'Semi DSM', type: 'Designer' });}} style={{ marginLeft: 8 }}>Add new line with init value</Button>
                            {
                                arrayFields.map(({ field, key, remove }, i) => (
                                    <div key={key} style={{ width: 1000, display: 'flex' }}>
                                        <Form.Input
                                            field={`${field}[name]`}
                                            label={`${field}.name`}
                                            style={{ width: 200, marginRight: 16 }}
                                        >
                                        </Form.Input>
                                        <Form.Select
                                            field={`${field}[role]`}
                                            label={`${field}.role`}
                                            style={{ width: 120 }}
                                            optionList={[
                                                { label: 'Engineer', value: 'Engineer' },
                                                { label: 'Designer', value: 'Designer' },
                                            ]}
                                        >
                                        </Form.Select>
                                        <Button
                                            type='danger'
                                            theme='borderless'
                                            icon={<IconMinusCircle />}
                                            onClick={remove}
                                            style={{ margin: 12 }}
                                        />
                                    </div>
                                ))
                            }
                        </React.Fragment>
                    )}
                </ArrayField>
                <ComponentUsingFormState />
            </Form>
        );
    }
}

Environment

- OS:
- browser:

Anything else?

No response

DualWield commented 1 year ago

@pointhalo any progress?

pointhalo commented 1 year ago

@pointhalo any progress?

Sorry, don’t have time to look at ArrayField related issues recently. I'll try to keep track of this issue this month

This is a case under specific recurrence conditions and will only appear when allowEmpty is enabled. If your scene does not have a strong demand for this, you can remove this prop first as a temporary solution.