我偶然发现了useState范围的问题。我正在尝试创建一个动态的Bootstrap窗体,用户可以在其中向该组添加更多行(这些行将包含与能源相关的数据)。当我在这些字段中输入内容时,enterEnvironmentData函数将激发空数据。有人可以向我解释吗?我的错误在哪里?
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(
<Form.Row key={ rowNames[i] }>
<Col>
<Form.Label>
Environment
</Form.Label>
<Form.Control
type="text"
data-group={ name }
data-row={ rn }
value={ arr[i][rn].envName }
onChange={ enterEnvironmentData }
/>
</Col>
<Col>
<Form.Label>
Heating Costs
</Form.Label>
<Form.Control
type="number"
data-group={ name }
data-row={ rn }
value={ arr[i][rn].heatingCosts }
onChange={ enterEnvironmentData }
/>
</Col>
<Col>
<Form.Label>
Water Costs
</Form.Label>
<Form.Control
type="number"
data-group={ name }
data-row={ rn }
value={ arr[i][rn].waterCosts }
onChange={ enterEnvironmentData }
/>
</Col>
<Col>
<Form.Label>
Gas Costs
</Form.Label>
<Form.Control
type="number"
data-group={ name }
data-row={ rn }
value={ arr[i][rn].gasCosts }
onChange={ enterEnvironmentData }
/>
</Col>
<Col>
<Form.Label>
Environment Costs
</Form.Label>
<Form.Control
type="number"
data-group={ name }
data-row={ rn }
value={ arr[i][rn].environmentCosts }
onChange={ enterEnvironmentData }
/>
</Col>
<Col>
<Form.Label>
Frazzle
</Form.Label>
<Form.Control
type="number"
data-group={ name }
data-row={ rn }
value={ arr[i][rn].frazzle }
onChange={ enterEnvironmentData }
/>
</Col>
</Form.Row>
);
};
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>
<Form.Label>
Elements Amount
<Form.Control
type="number"
name="group0"
value={ groupsData["group0"].rowsAmount }
onChange={ toggleChangeRowsAmount }
/>
<Button
variant="info"
name="group0"
onClick={ addRows }
>
Add
</Button>
</Form.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>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<div class="react"></div>
P.S。尚未填写此表格的任何内容。