简体   繁体   中英

Vuex and mysql connection object: Do not mutate vuex store state outside mutation handlers

I've got an electron application that uses mysql package to connect to my database directly. What I'm trying to do is to store connection object created with mysql.createConnection() in the Vuex state. Then I want to fetch some numbers from the database using this object.

I got this code for Vuex store:

const state = {
  connectionObject: null,
  numbers: [],
};

const getters = {
  getNumbers: state => state.numbers,
  getConnectionObject: state => state.connectionObject,
};

const mutations = {
  SET_NUMBERS(state, numbers) {
    state.numbers = Object.assign({}, numbers);
  },
  SET_CONNECTION_OBJECT(state, connection) {
     state.connectionObject = connection;
  },
};

const actions = {
  fetchNumbers({ state, commit }) {
    const connection = _.cloneDeep(state.connectionObject);
    connection.query({
      sql: 'SELECT * FROM `numbers`',
      timeout: 40000,
    }, async (error, results) => {
      if (error instanceof Error) {
        throw new Error(error);
      }
      commit('SET_NUMBERS', await results);
    });
  },
  connectToDatabase({ commit }, data) {
    const connection = mysql.createConnection(data);
    return new Promise((resolve, reject) => {
      connection.connect(async (err) => {
        if (err) {
          return reject(err);
        }
        commit('SET_CONNECTION_OBJECT', await connection);
        commit('SET_DB_CONNECTION_STATE', data);
        return resolve(connection);
      });
    });
  },
};

What happens is once I run the code I get Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] Do not mutate vuex store state outside mutation handlers." and this error is thrown when connection.query() is executed.

I have a hard to time understand why it doesn't work as I clone connectionObject from state after all. Seem like its observers get cloned as well. Is there a way to avoid it?

The connection object is highly mutable, it can not be stored. Every connection you make does change properties of the connection object. I would only store the returns in the storage, the data update in to the actions and the connectionobject should be made accessable across vuex, beware making it global though, this would make your app easier to hack. One way to make it accessable is by simply declaring it a variable besides the state.

If you need further advice it would be greate to know which SQL package you used in order to give you some code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM