My friend and I are working on a React translator app that uses the Lexicala API. We have two selector components: one for the source language and one for the target language. Users will first select the source language, and based on what they choose, a second dropdown menu will populate with a list of target languages that are available. Does anyone have any suggestions for how we would make the state update in the source language selector component affect the second component?
I'm including the code (without the comments) for each component. If you think we're already doing something incorrectly, please let me know.
SourceLanguageSelector.js
import React, {useState, useEffect} from 'react';
import { encode } from "base-64";
let headers = new Headers();
headers.append('Authorization', 'Basic ' + encode(process.env.REACT_APP_API_USERNAME + ":" + process.env.REACT_APP_API_PASSWORD));
const SourceLanguageSelector = () => {
const [loading, setLoading] = useState(true);
const [items, setItems] = useState([
{ label: "Loading...", value: "" }
]);
const [value, setValue] = useState();
useEffect(() => {
let unmounted = false;
async function getLanguages() {
const request = await fetch("https://dictapi.lexicala.com/languages", {
method: 'GET', headers: headers
});
const body = await request.json();
console.log(body);
const sourceLang = body.resources.global.source_languages;
const langName = body.language_names;
const compare = (sourceLanguage, languageName) => {
return sourceLanguage.reduce((obj, key) => {
if (key in languageName) {
obj[key] = languageName[key];
}
return obj;
}, {});
}
const sourceLanguageNames = compare(sourceLang, langName);
if (!unmounted) {
setItems(
Object.values(sourceLanguageNames).map((sourceLanguageName) => ({
label: sourceLanguageName,
value: sourceLanguageName
}))
);
setLoading(false);
}
}
getLanguages();
return () => {
unmounted = true;
}
}, []);
return (
<select
disabled={loading}
value={value}
onChange={e => setValue(e.currentTarget.value)}>
{items.map(item => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</select>
);
};
export default SourceLanguageSelector;
TargetLanguageSelector.js
import React, { useState, useEffect } from 'react';
import { encode } from 'base-64';
let headers = new Headers();
headers.append('Authorization', 'Basic ' + encode(process.env.REACT_APP_API_USERNAME + ":" + process.env.REACT_APP_API_PASSWORD));
const TargetLanguageSelector = () => {
const [loading, setLoading] = useState(true);
const [items, setItems] = useState([
{ label: "Loading...", value: "" }
]);
const [value, setValue] = useState();
useEffect(() => {
let unmounted = false;
async function getLanguages() {
const request = await fetch("https://dictapi.lexicala.com/languages", {
method: 'GET', headers: headers
});
const body = await request.json();
console.log(body);
const targetLang = body.resources.global.target_languages;
const langName = body.language_names;
const compare = (targetLanguage, languageName) => {
return targetLanguage.reduce((obj, key) => {
if (key in languageName) {
obj[key] = languageName[key];
}
return obj;
}, {});
}
const targetLanguageNames = compare(targetLang, langName);
if (!unmounted) {
setItems(
Object.values(targetLanguageNames).map(target_languages =>
({
label: target_languages,
value: target_languages
}))
);
setLoading(false);
}
}
getLanguages();
return () => {
unmounted = true;
}
}, []);
return (
<select
disabled={loading}
value={value}
onChange={e => setValue(e.currentTarget.value)}>
{items.map(item => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</select>
);
};
export default TargetLanguageSelector;