1

I'm currently working on a custom WordPress plugin that includes multiple custom blocks.

The folder structure looks like this:

src/
- custom-block-one
- custom-block-two
- custom-block-three
- custom-block-four

The files are loaded in the build:

build/
- custom-block-one
- custom-block-two
- custom-block-three
- custom-block-four

I would like to integrate a Redux store.

The files are located in the store folder in the root directory, alongside build and src:

build/
src/
store/  <= Redux Store

When I try to include my store in one of the four blocks (edit.js), I get the message:

Store 'my-plugin/custom-storage' is already registered.

I only added this line:

import store from '../../store/custom-store.js';

Now, my question is:

  1. How can I prevent the error so that it is only included once?
  2. How can I create a global main.js file?

If I try to create one inside src/:

src/
- custom-block-one
- custom-block-two
- custom-block-three
- custom-block-four
- main.js  <- Global files

It is not being built.

This is the custom-store.js

import { createReduxStore, register } from '@wordpress/data';

const STORE_NAME = 'custom-block/counter';

// Definiere den anfänglichen Zustand
const DEFAULT_STATE = {
    count: 0,
};

// Definiere die Aktionen
const actions = {
    increment() {
        return { type: 'INCREMENT' };
    },
    decrement() {
        return { type: 'DECREMENT' };
    },
    setCount(value) {
        return { type: 'SET_COUNT', value };
    },
};

// Definiere den Reducer
function reducer(state = DEFAULT_STATE, action) {
    switch (action.type) {
        case 'INCREMENT':
            return { ...state, count: state.count + 1 };
        case 'DECREMENT':
            return { ...state, count: state.count - 1 };
        case 'SET_COUNT':
            return { ...state, count: action.value };
        default:
            return state;
    }
}

// Definiere die Selektoren
const selectors = {
    getCount(state) {
        return state.count;
    },
};

// Erstelle und registriere den Store
const store = createReduxStore(STORE_NAME, {
    reducer,
    actions,
    selectors,
});

register(store);

export default store;
5
  • are you importing the store file from 4 separate JS files? Keep in mind that the contents of your store will not survive a refresh, and you shouldn't be using the contents of your store for anything that's going to be saved, that's what attributes are for. You run the risk of block validation problems etc, since you need to be able to generate identical HTML for a given set of attributes and your blocks save component. Also remember that WP Data itself uses redux internally, it might be better to use WP Data instead for your custom store Commented Mar 19 at 16:39
  • If this is an attempt to make blocks share things then this is not the answer and there are other solutions such as context, but you'd need to share the reasons for it as the solution will depend on that Commented Mar 19 at 16:40
  • I have a list of files and would like to store them via apiFetch in the store. The data should then be available in every custom block. I want to prevent having to fetch the list again each time. Commented Mar 19 at 19:51
  • in that case it might be better to put all that in its own JS file with its own build target, register it as a script then declare it as a dependency of your block files. Then in the blocks themselves access the store and check if it exists but don't try to create it without that check. Otherwise all 4 blocks would need to be in the same bundle/build process. The edit component would not be the place to do store initialisation either. Alternatively WordPress has a concept of entities, it might be possible to reuse that, especially if you're fetching from a REST API Commented Mar 20 at 10:28
  • I'd also be mindful that if what you're fetching is posts and pages, even via a custom endpoint then there are better ways of doing that Commented Mar 20 at 10:30

1 Answer 1

1

The solution was simpler than expected. I just had to add the following to my store file.

// Check if store already exists
if (!select(STORE_NAME)) {
    register(store);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.