I would like to be able to store some form of dynamic structure in the state. Each input element calls the same function "handleFormInput". in "name" the input name is stored. In "value" the actual value.
After each change these values are stored in the state.
If the user now clicks on the form button, the function "handleForm" is called. This function checks the state and reacts accordingly.
My problem: I check the length of the array, which is always 0.
If I output everything via Console.log, however, I see the elements in the array, also correctly. What have I not considered?
Called on every input change made
handleFormInput(event){
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.state.saveFormData[name] = value;
this.setState({
saveFormData : this.state.saveFormData
}, () => {console.log(this.state.saveFormData)});
}
Called when "Submitting"
handleForm(){
var l = 0;
this.state.saveFormData.forEach(element => {
l ;
});
console.log(l); // output: 0
if(this.state.saveFormData.length == 0){
this.setState({ openNew: false })
console.log(this.state.saveFormData);
}else{
console.log(this.state.saveFormData);
alert('we found Data' JSON.stringify(this.state.saveFormData));
}
}
Ouput of console.log
Array []
length: 0
ort: "asd"
<prototype>: Array []
Working Example in a Nutshell
if you start with the input, the array is written to the state after each input. Stack Snippet already shows an empty array here. The console in the browser shows an array with one element but with a length of 0.
In the similar answers I find, it always has to do with the fact that the console does not map the exact moment of the array, but only shows a reference, and retrieves the data just in time when it is unfolded.
in my case it seems to behave differently. Since also in the console the array length of 0 is shown
function App() {
return ( < DataEditor / > );
}
class DataEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
def: [],
defRaw: [],
loaded: false,
isLoading: false,
openNew: false,
editFormLoaded: false,
editFormData: [],
saveFormData: []
}
}
handleFormInput(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.state.saveFormData[name] = value;
this.setState({
saveFormData: this.state.saveFormData
});
}
handleForm() {
console.log("The Array Length is propably zero but we can access the element")
console.log(this.state.saveFormData.ort);
console.log("Log the testet Array")
console.log(this.state.saveFormData);
if (this.state.saveFormData.length == 0) {
this.setState({
openNew: false
})
console.log(this.state.saveFormData);
} else {
console.log(this.state.saveFormData);
alert('we found Data' JSON.stringify(this.state.saveFormData));
}
}
render() {
return ( <
div >
<
input type = "text"
name = "ort"
onChange = {
(e) => this.handleFormInput(e)
}
/> <
button type = "button"
onClick = {
() => this.handleForm()
} > Test State Access and Array < /button> < /
div >
);
}
}
ReactDOM.render( < App / > , document.getElementById("root"));
<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 id="root"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
This has nothing to do with react, it's simply that on the inside array is still an instance of an object and can have it's properties modified the same way, without actually adding them to the iterable options.
Example here:
const array = [];
array.ort = "test";
console.log(array); // []
console.log(array.length); // 0
console.log(array.ort); // "test"
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
I suggest using an object instead and iterating over it's values with Object.values or Object.entries.
const object = {};
object.ort = "test";
console.log(object); // {ort: "test"}
console.log(Object.values(object).length); // 1
console.log(object.ort); // "test"
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>