Uncaught (in promise) ReferenceError: state is not defined

Появляется такая ошибка:введите сюда описаннияoverflow.com/image.jpg)введите сюда описание изображения

Использую vuex, методом проб понял, что приложение ломается из-за состояния isPostsLoading: false в компоненте postModule.js . Это состояние мы передаем в компонент PostsPageWithStore.vue , если закомментировать это состояние, то всё работает. Как можно это пофиксить?

import { createStore } from 'vuex'
import { postModule } from './postModule'

export default createStore({
  /* один модуль представляет из себя какой-то один изолированный кусочек состояния со своими getters, mutations, actions */
  modules: {
    /* post -  название модуля */
    post: postModule,
  },
})

<!-- компонент PostModule.js -->
import axios from 'axios'

export const postModule = {
  /* В поле state  мы описываем данные, которые будут в нашем приложении */
  state: () => ({
    posts: [],
    isPostsLoading: false,
    selectedSort: '',
    searchQuery: '',
    page: 1,
    limit: 10,
    totalPages: 0,
    sortOptions: [
      { value: 'title', name: 'По названию' },
      { value: 'body', name: 'По содержанию' },
    ],
  }),
  /* это некоторые computed св-ва анаогичные тем, что мы создавали в компонентах, это своего рода кэщируемые вычисляемые значения. Изменять состояния мы не можем, но можем изменять с помощью мутаций */
  getters: {
    sortedPosts(state) {
      return [...state.posts].sort((post1, post2) =>
        post1[state.selectedSort]?.localeCompare(post2[state.selectedSort])
      )
    },
    /* в новом computed свойстве мы используем старое */
    sortedAndSearchedPosts(state, getter) {
      return getter.sortedPosts.filter((post) =>
        post.title.toLowerCase().includes(state.searchQuery.toLowerCase())
      )
    },
  },
  /* Мтации представляют из себя функции, внутри которых мы (меняем состояние) меняем значение какого-то поля в состоянии. Для вызова мутаций используется функция commit   */
  mutations: {
    setPosts(state, posts) {
      state.posts = posts
    },
    // setIsPostsLoading(state, bool) {
    //   state.isPostsLoading = bool
    // },
    setSelectedSort(state, selectedSort) {
      state.selectedSort = selectedSort
    },
    setSearchQuery(state, query) {
      state.searchQuery = query
    },
    setPage(state, page) {
      state.page = page
    },
    setTotalPages(state, totalPages) {
      state.totalPages = totalPages
    },
  },
  /* Функции, которые внутри себя используют мутации, т.е. напрямую из actions менять состяние не рекомендуется, но мы можем использовать внутр экшенров - мутации. В свою очередь внутри экшенов мы делаем какие-то сайды эффектами (например получаем данные с сервера)  */
  actions: {
    /* commit - нужен для вызова мутаций, dispatch - для вызова других actions  */
    async fetchPosts({ state, commit }) {
      try {
        commit('setIsPostsLoading', true)
        const res = await axios.get(
          `https://jsonplaceholder.typicode.com/posts`,
          {
            params: {
              _page: state.page,
              _limit: state.limit,
            },
          }
        )
        /* Мы меняем totalPages, поэтому мы совершаем соответствующую мутацию. commit первым параметром принимает название, а вторым - результат вычислений  */
        commit(
          'setTotalPages',
          Math.ceil(res.headers['x-total-count'] / state.limit)
        )
        commit('setPosts', res.data)
      } catch (error) {
        console.log(error)
      } finally {
        commit('setIsPostsLoading', false)
      }
    },
    /* эта функция вызывается, когда пользователь доскроллил до конца страницы */
    async loadMorePosts({ state, commit }) {
      try {
        commit('setPage', state.page + 1)

        const res = await axios.get(
          `https://jsonplaceholder.typicode.com/posts`,
          {
            params: {
              _page: state.page,
              _limit: state.limit,
            },
          }
        )
        commit(
          'setTotalPages',
          Math.ceil(res.headers['x-total-count'] / state.limit)
        )

        /* В этом случае мы посты не перезаписываем, а добавляем в конец массива */
        commit('setPosts', [...state.posts, ...res.data])
      } catch (error) {
        console.log(error)
      }
    },
  },
  namespaced: true,
}

<!-- компонент PostsPageWithStore.vue -->
<template>
  <div>
    <h1>Страница с постами</h1>
    <!-- <my-input v-focus v-model="searchQuery" placeholder="Поиск..." /> -->
    <div class="app__btns">
      <my-button @click="showDialog">Cоздать пост</my-button>

      <!-- <my-select v-model="selectedSort" :options="sortOptions" /> -->
    </div>
    <my-dialog v-model:show="dialogVisible">
      <post-form @create="createPost" />
    </my-dialog>

    <post-list
      :posts="sortedAndSearchedPosts"
      @remove="removePost"
      v-if="!isPostsLoading"
    />
    <div v-else class="loader">Загрузка...</div>
    <div v-intersection="loadMorePosts" class="observer"></div>
  </div>
</template>

<script>
import PostForm from '@/components/PostForm.vue'
import PostList from '@/components/PostList.vue'
/*  Чтобы не прописывать такой долгий путь, придумали специальные функции mapState, mapActions и тд. :posts="$store.getters.post/sortedAndSearchedPosts"   */
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
  /*  поле components - для регистации комопнентов */
  components: { PostList, PostForm },
  data() {
    return {
      dialogVisible: false,
    }
  },
  /* Работа с mutations, actions ведется в поле methods */
  methods: {
    ...mapMutations({
      setPage: 'post/setPage',
    }),
    ...mapActions({
      loadMorePosts: 'post/loadMorePosts',
      fetchPosts: 'post/fetchPosts',
    }),

    /* мы подписались на это событие и принимаем post из компонента PostForm */
    createPost(post) {
      this.posts.push(post)
      this.dialogVisible = false
    },
    removePost(post) {
      this.posts = this.posts.filter((p) => p.id !== post.id)
    },
    showDialog() {
      this.dialogVisible = true
    },
  },
  /* хук для того, чтобы сделать запрос на сервер после маунта  */
  mounted() {
    this.fetchPosts()
  },

  computed: {
    ...mapState({
      posts: () => state.post.posts,
      isPostsLoading: () => state.post.isPostsLoading,
      selectedSort: () => state.post.selectedSort,
      searchQuery: () => state.post.searchQuery,
      page: () => state.post.page,
      limit: () => state.post.limit,
      totalPages: () => state.post.totalPages,
      sortOptions: () => state.post.sortOptions,
    }),
    ...mapGetters({
      sortedPosts: 'post/sortedPosts',
      sortedAndSearchedPosts: 'post/sortedAndSearchedPosts',
    }),
  },

  watch: {},
}
</script>

<style>
.app__btns {
  margin: 15px 0;
  display: flex;
  justify-content: space-between;
}

.page__wrapper {
  display: flex;
  margin-top: 15px;
}

.page {
  border: 1px solid black;
  padding: 10px;
}

.current-page {
  border: 3px solid teal;
}

.observer {
  height: 30px;
  background: green;
}
</style>


Ответы (0 шт):