使用useState React挂钩时从状态获取空数据

时间:2020-11-12 12:58:18

标签: reactjs react-hooks use-state

我偶然发现了useState范围的问题。我正在尝试创建一个动态的Bootstrap窗体,用户可以在其中向该组添加更多行(这些行将包含与能源相关的数据)。因此,当我添加2行以上并开始更改输入的值时, enterEnvironmentData 函数将触发空数据(最后一个console.log)。我的错误在哪里?为什么状态数据(groupsData.group0.rows数组)为空?

const { useState, useEffect } = React;

const App = () => {

const [ defaultData, ] = useState(
    {
        envName: undefined,
        heatingCosts: 0,
        waterCosts: 0,
        gasCosts: 0,
        environmentCosts: 0,
        frazzle: 0
    }
);
const [ groupsData, setGroupsData ] = useState( {
    group0: {
        id: 0,
        rowsAmount: 0,
        rows: []
    }
} );

// *enterEnvironmentData* function fires when input fields are changed

const enterEnvironmentData = (event) => {
    console.log(event.target.value);
    const group = event.target.getAttribute('data-group'),
        row = event.target.getAttribute('data-row');
    
    console.log("groupsData - ", groupsData);
    console.log("data-group - ", group);
    console.log("data-row - ", row);
    console.log("groupsData[", group, "]", groupsData[group]);
    console.log("groupsData[", group, "].rows", groupsData[group].rows); // rows array is empty ???
};

let [ environment, setEnvironment] = useState( {
    group0: [],
    group1: []
} );

// *toggleChangeRowsAmount* fires when changing Form.Control's value (elements amount)

const toggleChangeRowsAmount = (event) => {
    console.log(event.target);
    let value = +event.target.value,
        name = event.target.name;

    if ( value <= 0 ) {
        value = 0;
    } else {
        setGroupsData({
            ...groupsData,
            [name]: { ...groupsData[name], rowsAmount: value }
        })
    }
};

// *addRows* fires when clicking on "Add" button

const addRows = (event) => {
    const name = event.target.getAttribute('name'),
        rows = groupsData[name].rowsAmount,
        length = groupsData[name].rows.length;
    let arr = [],
        rowNames = [];
    
    for (let i = length; i < rows+length; i++) {
        let newRow = `row${i}`;
        rowNames.push(newRow);
        arr.push(
            {
                [newRow]: defaultData
            }
        );
    }

    setGroupsData({
        ...groupsData,
        [name]: {
            ...groupsData[name],
            rows: [
                ...groupsData[name].rows,
                ...arr
            ]
        }
    });

    let items = [];
    
    for (let i = 0; i < arr.length; i++ ) {
        let rn = rowNames[i];
        items.push(
            <div key={ rowNames[i] }>
                <div>
                    <label>
                        Environment
                    </label>
                    <input
                        type="text"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].envName }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Heating Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].heatingCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Water Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].waterCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Gas Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].gasCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Environment Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].environmentCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Frazzle
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].frazzle }
                        onChange={ enterEnvironmentData }
                    />
                </div>
            </div>
        );
    };

    setEnvironment({
        ...environment,
        [name]: [
            ...environment[name],
            ...items
        ]
    });
};

useEffect(
    () => {
        console.log("groupsData - ", groupsData, ", environment - ", environment);
    },
    [ groupsData, environment ]
)
    
return (
    <div className="EntryForm">
        <div className="container">
            <form>
                <div key="group0" >
                    <h4>
                        Group
                    </h4>
                    <label>
                        Elements Amount                      
                        <input
                            type="number"
                            name="group0"
                            value={ groupsData["group0"].rowsAmount }
                            onChange={ toggleChangeRowsAmount }
                        />
                        <button
                            name="group0"
                            onClick={ addRows }
                        >
                            Add
                        </button>
                    <label>
                    {
                        environment["group0"].map( env => env)
                    }
                </div>
            </Form>
        </div>            
    </div>
)
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>  
<div class="react"></div>

P.S。尚未通过此表格提交任何内容。

当我添加行至少两次

时,我发现必要的数据并不为空

0 个答案:

没有答案