Comments (1)
I also came across this when starting a new project and trying to use Inject.
I hacked up a start for a new inject decorator (called inject3 below to indicate stage 3 decorators).
It's not super great at this point, but it does work in basic testing. You have to configure Vite to use the stage 3 decorators, which requires using either Babel or Typescript. I'm using Babel, so this is basically what I did: https://dev.to/kiranmantha/ecmascript-decorators-with-vite-ilg.
There are two specific challenges that I'm aware of right now:
- Need to see if there's a way to get the store(s) off of the React.Context (MobxProviderContext).
-
I'm sure it's doable, but can't use useContext() because this is a class component, and can't just use
static contextType: MobxProviderContext
in the wrapper class because I'm adding the store props to regular props in the Injector's constructor before calling super(propsWithStores), and I can't access the React.Context until super() has been called, but I need the context before calling super() to get the stores from it. -
To get around this for now, I just exported an object from my root store, "stores", and am importing that into the inject3.ts file. This is not ideal for testing, though Jest can rewrite imports when testing and also the stores will be overridden if passed in as direct props just like the existing inject decorator.
- Because of adding the store(s) to the props before calling super(propsWithStore), Mobx itself is logging a warning about passing the same props to the superclass that were passed into the subclass constructor.
I haven't really tested other than it works ala @inject("store")
in the small app that I've just started working on, having used it in a couple of components.
I thought maybe we could discuss and maybe someone has some improvements.
I realize that Provider/Inject are supposed to be deprecated in Mobx v7, but I will probably still continue to use them because I am not at all a fan of stateful function components (other when state is via external stores) and am definitely not a fan of hooks. (Signals from Solid, Preact, etc. are better, but still not as good as good ol' Mobx).
Funny how all of these "solutions" have been created over the past several years to problems that I never had as a user of Mobx. Hooks give me almost no advantages because of Mobx, and a lot of disadvantages. I still do web apps the same way that I did back in 2016 when starting with React, getting a lot done without wasting time constantly learning the next "solution." :)
// file: inject3.ts
import { stores } from "../src/_store/store";
type IValueMap = Record<string, any>;
// this is a "decorator factory" that takes in the stores to inject and returns a stage 3 class decorator
export function inject3(
// first arg could be a function that extracts a specific shape of state from the available stores
// https://github.com/mobxjs/mobx-react#provider-and-inject
...storeNames: Array<any>
) {
// get store(s) that should be added to props. These must be provided by the Provider component higher up
// in the component tree, otherwise an error will be thrown
// TODO: would it be possible to typecheck store names at build time rather than runtime?
return function (
target: any,
{ kind, name }: ClassDecoratorContext,
): typeof target {
if (kind === "class") {
// return a class that extends the target class with the store(s) injected as additional props
const Injector = class extends target {
constructor(props: IValueMap) {
// determine which store(s) to inject; explicit props override this behavior
const propsWithStores = storeNames.reduce(
(acc, storeName) => {
if (storeName in props) return acc; // props override injection (useful for testing)
acc[storeName] = stores[storeName];
return acc;
},
{} as IValueMap,
);
// this causes a warning from Mobx about passing a different value into super from what was passed
// into this constructor
super(propsWithStores);
this.displayName = name;
}
} as typeof target;
// rename the Injector to include the injectee name, etc., for ergonmics
Object.defineProperty(Injector, "name", {
writable: false,
enumerable: false,
configurable: true,
value: `${name}_With_${storeNames.join("_")}`,
});
return Injector;
}
return target;
};
}
from mobx.
Related Issues (20)
- `StubArray` workaround is incompatible with terser's `unsafe_arrows` option HOT 4
- mobx-react-lite component wrapped in `observer` renders twice in latest Next.js HOT 3
- Peer dependency issue for [email protected] HOT 4
- Migration from Mobx 4 > 6 HOT 6
- `trackDerivedFunction` pre-allocates memory for new deps array too aggressively HOT 1
- Invalid/extra warning in observable.box(array)
- Recommended pattern `MyComp = observer(function MyComp() {...})` leads to subtle bug
- Storing a Lit template in a mobx store does not work HOT 3
- Cannot update past `6.10.0` HOT 1
- Supporting of new Set methods in observable Sets HOT 3
- [feature] Investigate running MobX on top of signals standard / polyfill HOT 1
- [eslint-plugin-mobx] ESLint v9 Support
- `isolateGlobalState: true` can cause conflicts that prevent observable registration
- [mobx-react] `Maximum update depth exceeded` error since `mobx-react@8` HOT 5
- makeAutoObservable can't detect a generator after adding a default parameter value HOT 6
- Incompatible with React Forget compiler HOT 3
- [eslint-plugin-mobx] `mobx/exhaustive-make-observable` autofix behavior should be inversed HOT 4
- Converting functions to actions (autoActions?) in deep enhancer leads to bugs HOT 5
- @action decorators on fields do not convert the field value into action HOT 8
- New computed decorator does not apply action to setter HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mobx.