작성
·
283
0
코지코더님 안녕하세요.
양질에 강의에 감사드리며, 55강을 듣다가 2가지 의문점이 생겨 문의 드립니다.
onUnmounted hook에서 toastTimer를 삭제하는 로직의 동작이 강의 내용과 상이하여 문의 드립니다.
강의와 동일하게 소스를 작성하였는데, 콘솔을 보면
onUnmounted
timeout
이 출력됩니다. timeout이 출력되지 않아야 맞는 동작인 것 같은데 왜 clear 되지 않는 걸까요?
_id.vue 전체 소스는 하단에 첨부하였습니다!
const toastTimer = ref(null);
const triggerToast = (message, type = 'success') => {
toastMessage.value = message;
toastType.value = type;
showToast.value = true;
toastTimer.value = setTimeout(() => {
console.log('timeout');
toastMessage.value = '';
toastType.value = '';
showToast.value = false;
}, 3000);
};
onUnmounted(() => {
console.log('onUnmounted');
clearTimeout(toastTimer.value);
});
강의에서 const toastTimer = ref(null); 과 같이 timer를 담는 변수에도 ref로 감싸셨는데요,
ref로 감싸지 않고 let 으로 선언하면 안 되나요?
----
<template>
<h2>To-Do Page</h2>
<div v-if="loading">Loading...</div>
<form
v-else
@submit.prevent="onSave">
<div class="row">
<div class="col-6">
<div class="form-group mb-2">
<label class="my-2">Todo Subject</label>
<input type="text" class="form-control" v-model="todo.title">
</div>
<button type="button" class="btn btn-outline-dark">Cancel</button>
<button
type="submit"
class="btn btn-primary ms-2"
:disabled="!todoUpdated"
@click.stop="onSave"
>Save</button>
</div>
<div class="col-6">
<div class="form-group">
<label class="my-2">Status</label>
</div>
<button
type="button"
class="btn btn-primary"
:class="statusBtnClass"
@click="toggleTodoStatus"
>{{ statusBtnLabel }}</button>
</div>
</div>
</form>
<Toast v-if="showToast" :message="toastMessage" :type="toastType"></Toast>
</template>
<script>
import { useRoute } from 'vue-router';
import { ref, computed, onUnmounted } from 'vue';
import _ from 'lodash';
import { getTodoItem, putTodoItem } from '@/api';
import Toast from '@/components/Toast.vue';
export default {
setup() {
const route = useRoute();
const todoId = route.params.id;
const todo = ref(null);
const originTodo = ref(null);
const loading = ref(true);
const showToast = ref(false);
const toastType = ref('success');
const toastMessage = ref('');
const toastTimer = ref(null);
const triggerToast = (message, type = 'success') => {
toastMessage.value = message;
toastType.value = type;
showToast.value = true;
toastTimer.value = setTimeout(() => {
console.log('timeout');
toastMessage.value = '';
toastType.value = '';
showToast.value = false;
}, 3000);
};
onUnmounted(() => {
console.log('onUnmounted');
clearTimeout(toastTimer.value);
});
const getTodo = async () => {
try {
const res = await getTodoItem(todoId);
todo.value = res.data;
originTodo.value = { ...res.data };
loading.value = false;
} catch (err) {
triggerToast('Error occurred!', 'danger');
}
};
const statusBtnClass = computed(() => (todo.value.done ? 'btn-success' : 'btn-danger'));
const statusBtnLabel = computed(() => (todo.value.done ? 'Completed' : 'Incompleted'));
const toggleTodoStatus = () => {
todo.value.done = !todo.value.done;
};
const todoUpdated = computed(() => !_.isEqual(todo.value, originTodo.value));
const onSave = async () => {
try {
const { data } = await putTodoItem(todoId, todo.value);
originTodo.value = { ...data };
triggerToast('Successfully saved!');
} catch (err) {
triggerToast('Error occurred!', 'danger');
}
};
getTodo();
return {
todo,
loading,
statusBtnClass,
statusBtnLabel,
toggleTodoStatus,
todoUpdated,
onSave,
showToast,
toastMessage,
toastType,
};
},
components: {
Toast,
},
};
</script>
<style scoped>
</style>
답변 2
1
질문 1. form 태그에 @submit에서 onSave 함수를 사용하고 있고 button에도 @click에서 onSave를 실행해하고 있습니다. 그래서 setTimeout이 두번 실행되고 clear 할때 하나는 clear 되지 않아서 그런거 같아요.
onSave를 한번만 실행할수 있게 둘중에 하나를 지우시면 잘 작동할거 같네요
질문 2. let 사용하셔도 됩니다
확인해보시고 안되면 또 댓글 남겨주세요 ^^
0