Хотите повторно заполнить массив полей Formik данными, полученными из SharePoint, при изменении значения раскрывающегося списка - PullRequest
0 голосов
/ 02 июля 2019

Прежде всего, я уже нашел способ добиться этого, но у меня есть оговорки в отношении этого подхода, поскольку я использую объект состояния класса React, которого я хотел избежать.

Formik определен внутри функции рендеринга компонента класса React, поэтому я не могу делать вещи setFieldValue или Reset_Form программно. В качестве обходного пути я в основном собираю объект ref из formik во время рендера и сохраняю его в состоянии. Затем я использую объект ref в событии изменения моего раскрывающегося списка, как показано в функции On_Change_Select_Dropdown файла form.tsx. Объект ref formik позволяет мне использовать его встроенные функции для внешнего управления формой.

Другой подход, который работает, - это модификация объекта значений Formik. Но разве это хорошая идея?

Я нахожусь на начальном уровне в response.js, поэтому мне нужно экспертное мнение о недостатках этого подхода и любых возможных альтернативах, которые не требуют масштабного рефакторинга кода, так как он довольно близок к завершению.

form.tsx

render() {
    return (
        <div className="app">
            <h1 style={{ textAlign: "center" }}>Cash Debt Report</h1>
            <Formik
                onSubmit={(e, { setSubmitting }) => {this.On_Submit(e, setSubmitting)}}
                onReset={e => this.On_Reset(e)}
                enableReinitialize={true}   
                validateOnChange={false}
                ref={(e) => { this.state.formik = e }}
                initialValues={this.Get_Initial_Values(fields)}
                render={({ values, errors, isSubmitting, touched }) => {
                    this.On_Touched(touched, values);
                    const errorMessageShow = Object.keys(errors).length > 0 ? 'error' : 'hidden';
                    return (
                        <div>
                            <Form>
                                <div>
                                    {this.Render_Fields(fields, values)}
                                </div>
                                {this.Render_Grid_Accounts('cash_accounts', values)}
                            </Form>
                        </div>
                    }
            }
    );
}

Render_Fields(inputs, values) {
    return (
        Object.keys(inputs).map((field_key) => {
            let input = inputs[field_key];
            if (input.auto_render) {
                if (input.type === 'select') {
                    return this.Render_Select(input.name, input.label, input.name, values);
                }
                else if (input.type === 'checkbox') {
                    return this.Render_Check_Box(input.name, input.value, input.label, values);
                }
                else if (input.type === 'textarea') {
                    return this.Render_Text_Area(input.name, input.value, input.label, values);
                }
                else if (input.type === 'text') {
                    return this.Render_Text(input.name, input.value, input.label, values);
                }
                else { return }
            }
            else { return }
        })
    );
}

On_Change_Select_Dropdown(e,values) {
     let url = sp_config.paths.api + "/_api/web/lists/getbytitle('" + 
     sp_config.lists.cash_debt_acc.title + "')/items"+
                    "?$select=*,Company/Id,Currency/Id" +
                    "&$expand=Company,Currency" +
                    "&$orderby=Created desc"
                    "&$top=1" +
                    "&$filter=Division eq '" + division + "' and 
                    Company/Id eq '" + company + "'";       
   Get(url).then((res) => {                     
       let results = res.data['d'].results;
       let cash_accounts: object[] = [];
       let acc_obj;
       if (results.length > 0) {
       results.map(v => {
           acc_obj = acc_obj_cash;
           acc_obj.account_no = v.AccountNo;
           cash_accounts.push(acc_obj) : debt_accounts.push(acc_obj);
       });
        //Repopulate Field Array with new items fetched from SharePoint
        this.state.formik['setFieldValue']('cash_accounts', [acc_obj_cash]);

        //The following approach works but I have
        //I am not sure if modifying the values object of formik is 
        //a good idea
        //values['cash_account'] = [acc_obj_cash]
        }
    });
}

fields.tsx

    export const acc_obj_cash = { 
        category: 'Cash', bank_name: '', 
        account_type: '', account_no: '', 
        book_balance: '', bank_balance: '', 
        outstanding_bal: '', 
        variance: '0', 
        currency: '' 
    };

    export const fields = {
        division: { label: 'Division', type: 'select', name: 'division', value: '', auto_render: true, read_only: false },
        cash_accounts:{
                label: ['Account Type', 'Bank Name', 'Account No', 'Book Balance', 'Bank Balance'],
                heading: ["Cash Accounts"],
                name: 'cash_accounts',
                type: 'array',
                auto_render: true,
                read_only: ['variance'],
                value: new Array(2).fill(acc_obj_cash)
        },

    };
    export default fields;
...