I am writing a react app to fetch vocabulary from a backend database and then display it to the user, along with some information about each particular word. My problem is that I can't get the word to display inside render() as the index of the array is undefined, however according to chrome devtools the array is fully defined.
Here's my code:
import React from 'react';
import "./Vocab.css"
class Vocab extends React.Component {
//HEADER HEADER HEADER
state = {
vocabulary: null,
var2: null
};
componentDidMount(){
//Initializing Routine Here
this.getVocab()
}
getVocab = () => {
var newVocab = [];
if(this.state.vocabulary == null){
newVocab = newVocab;
}
else{
newVocab = [this.state.vocabulary];
}
this.props.HandleFetch("GET", this.props.backLink + "vocab")
.then(r => JSON.parse(r))
.then(data => newVocab.push(data[0]))
.then(this.setState({vocabulary:newVocab}))
}
//In render() variable display and the if/else statements are used exclusively for testing purposes
render() {
var display = "X";
if(this.state.vocabulary == null){
display = "Y";
}
else{
console.log(this.state.vocabulary); //Outputs the array
console.log(this.state.vocabulary[0]) //Outputs "undefined"
display = "Z";
}
return (
<>
<h1>Test</h1>
{display}
</>
);
}
}
export default Vocab;
The output of console.log(this.state.vocabulary):
0:
Definition: "TestDef"
IPA: "TestIPA"
IsCard: true
Language: "TestLang"
LastStudyDate: "2021-01-27"
Mnem: ""
PoS: "TestPO"
Source: "TestDict"
SourceLearned: "TestSource"
Word: "Test"
The output of this.state.vocabulary[0]:
undefined
Additionally, according to chrome devtools and through typing $r.state.vocabulary[0] in the console I get the dictionary at the array's index, which I need:
{Word: "Test", Mnem: "", LastStudyDate: "2021-01-27", SourceLearned: "TestSource", IsCard: true, …}
In the console the array is fully navigable, but the web page itself won't render it. Any idea what I might be doing wrong?
UPDATE I was able to add a button the onClick goes to a function which prints out vocabulary and vocabulary[0]. This DOES work, but the render() function and componentDidUpdate() function still cannot access vocabulary[0]. I don't see anything in the react documentation that talks about a setState() finishing or any function happening after componentDidUpdate().
Additionally during some earlier testing I tried to console.log newVocab[0] before assigning it to state in a .then string. This worked, but outputted in the console only after all my other console calls, which indicates that it is happening after the component rerender and update cycle, even though I was calling it before I called setState().
My current test code so far:
import "./Vocab.css"
class Vocab extends React.Component {
//HEADER HEADER HEADER
state = {
vocabulary: null,
var2: null
};
componentDidMount(){
//Initializing Routine Here
this.getVocab()
}
componentDidUpdate(){
console.log("Vocab update");
console.log(this.state.vocabulary);
console.log("Vocab[0] update");
console.log(this.state.vocabulary[0]);
///Outputs the vocabulary array, and then 'undefined'
}
getVocab = () => {
var newVocab = [];
if(this.state.vocabulary == null){
newVocab = newVocab;
}
else{
newVocab = this.state.vocabulary;
}
this.props.HandleFetch("GET", this.props.backLink + "vocab")
.then(r => JSON.parse(r))
.then(data => newVocab.push(data[0]))
.then(this.setState({vocabulary:newVocab}))
}
logVocab = () => {
console.log("Vocab");
console.log(this.state.vocabulary);
console.log("Vocab[0]");
console.log(this.state.vocabulary[0]);
///Outputs the vocabulary array, and then the dictionary at index[0].
}
render() {
var display = "X";
if(this.state.vocabulary == null){
display = "Y";
console.log("Y");
}
else{
console.log("Vocab Z");
console.log(this.state.vocabulary);
console.log("Vocab[0] Z");
console.log(this.state.vocabulary[0]);
display = "Z";
///Outputs the vocabulary array, and then 'undefined'
}
return (
<>
<h1>Test</h1>
{this.state.vocabulary ? this.state.vocabulary[0] : ""}
<button onClick = {this.logVocab}> CLICK </button>
</>
);
}
}
export default Vocab;
rfromthis.props.HandleFetch("GET", this.props.backLink + "vocab") .then(r => JSON.parse(r))please[{"Word": "Test", "Mnem": "", "LastStudyDate": "2021-01-27", "SourceLearned": "TestSource", "IsCard": true, "IPA": "TestIPA", "PoS": "TestPO", "Definition": "TestDef", "Source": "TestDict", "Language": "TestLang"}]