#javascript #reactjs #react-hooks #use-effect #use-state
Вопрос:
У меня есть код ниже:
const [files, setFiles] = useState([]);
const [greeting, setGreeting] = useState(0);
const [menu, setMenu] = useState([]);
const [options, setOptions] = useState([]);
var customer_id = 1;
useEffect(() => {
async function getFiles() {
var data = {
"customer-id": customer_id
};
let response = await axios.post(`http://localhost:2000/files/get-files`, data)
//let response = await axios.post(`/files/get-files`, data)
for (let i = 0; i < response.data.length; i ) {
setOptions(oldArray => [...oldArray, {'value': response.data[i]['id'], 'label': response.data[i]['name']}])
}
setFiles(response.data)
}
async function getIVR() {
var data = {
"customer-id": customer_id
};
let response = await axios.post(`http://localhost:2000/files/get-ivr`, data)
//let response = await axios.post(`/files/get-ivr`, data)
setGreeting(response.data[0]['greeting'])
setMenu(response.data[0]['menu'])
}
getFiles()
getIVR()
}, []);
var test = (options.find(x => x.value === greeting))
console.log(test.get('label'))
Приведенный выше код возвращает ошибку:
TypeError: Cannot read property 'get' of undefined
Это связано с тем, что при первом рендеринге метка не существует, так как параметры еще не заполнены. Однако, когда я просто console.log(тест), я вижу, что через несколько мс он заполняется, как показано в журналах:
27GreetingMenu.js:53 undefined
GreetingMenu.js:53 undefined
GreetingMenu.js:53 {value: 3, label: "Test Menu"}
GreetingMenu.js:53 {value: 3, label: "Test Menu"}
GreetingMenu.js:53 {value: 3, label: "Test Menu"}
GreetingMenu.js:53 {value: 3, label: "Test Menu"}
Как я могу сделать так, чтобы я всегда мог получить значение метки. Этого можно достичь, каким-то образом дождавшись завершения эффекта использования, что означает, что параметры хороши, а это значит, что я могу их проанализировать.
Дай мне знать!
Комментарии:
1. Не связано с вашей проблемой, но есть ли какая-либо причина, по которой у вас есть 2 асинхронные функции внутри вашего useEffect.?
Ответ №1:
Я думаю, что вы пытаетесь решить здесь неправильную проблему.
Во — первых: Это связано с тем, что при первом рендеринге метка не существует, так как параметры еще не заполнены-это не совсем верно. Проблема не в том, что label
свойство не задано, оно test
не определено, так find
как не получило совпадения.
Вместо того, чтобы пытаться дождаться useEffect
завершения a (вы не можете напрямую), вы должны просто выполнить простую проверку, чтобы убедиться test
, что он определен, прежде чем использовать его в качестве объекта.
var test = (options.find(x => x.value === greeting))
// Easiest solution
console.log(test?.get('label'))
// Without nullsafe operator
console.log(test amp;amp; test.get('label'))
В качестве примечания, поскольку вы можете столкнуться с этой ошибкой в следующем: я не вижу get
метода, добавляемого к объектам внутри options
? Таким образом, вы можете получить ошибку, сказав .get
, что это не функция.
Похоже, может быть, вы предполагаете test
, что это будет неизменяемый объект? Но я нигде не вижу кода, подтверждающего это.
Ответ №2:
Я думаю, что вы можете использовать useEffect
в зависимости от изменений options
и greeting
Когда параметры имеют значение, вы можете получить метку
useEffect(()=>{
if(options amp;amp; options.length > 0){
var test = (options.find(x => x.value === greeting));
console.log(test amp;amp; test.get('label'));
}
},[options, greeting]);