M.S.
M.S.

Reputation: 79

Explicit types in React Typescript for custom global state hook

I found a great working React Hook to manage the global state of my application. But the example was written in Javascript and I am working in TypeScript, so the types need to be implicitly set.

This is my store.ts:

import { useState, useEffect } from 'react';

let globalState = {};
let listeners = [];
let actions = {};

export const useStore = (shouldListen = true) => {
  const setState = useState(globalState)[1];

  const dispatch = (actionIdentifier, payload) => {
    const newState = actions[actionIdentifier](globalState, payload);
    globalState = { ...globalState, ...newState };

    for (const listener of listeners) {
      listener(globalState);
    }
  };

  useEffect(() => {
    if (shouldListen) {
      listeners.push(setState);
    }

    return () => {
      if (shouldListen) {
        listeners = listeners.filter((li) => li !== setState);
      }
    };
  }, [setState, shouldListen]);

  return [globalState, dispatch];
};

export const initStore = (userActions, initialState) => {
  if (initialState) {
    globalState = { ...globalState, ...initialState };
  }
  actions = { ...actions, ...userActions };
};

This is the positions_store.ts, managing the update of the coordinates of an element (as a start):

import { initStore } from './store';

interface GlobalState {
  position: { x: number; y: number };
}

const configureStore = () => {
  const actions = {
    TOGGLE_FAV: (position: { x: number; y: number }) => {
      return { position: { x: position.x, y: position.y } };
    },
  };
  initStore(actions, {
    position: { x: 0, y: 0 },
  });
};

Typescript gives me an error for listeners, actionIdentifier, payload, userActions and initialState for implicity having 'any' type.

I am struggling for hours now and getting nowhere... Any help appreciated!

Upvotes: 0

Views: 403

Answers (1)

nolan
nolan

Reputation: 467

Actually, the types strongly depend on how you design the data structure, this is an example of the listeners type:

let listeners: ((state: typeof globalState) => void)[] = [];

Upvotes: 1

Related Questions