Comments (2)
If you really sure you need to use effector in that way you could just create one generalized effect, which will work in exactly the same way as you wish:
const getStateFx = createEffect(store => store.getState())
Effector relies on declarative store connections, this allows to perform many optimizations and current hot take: future dynamic models spawning will be significantly slower without declarations which tells what will be used ahead of time.
There also cannot be a visualization with totally dynamic store reading: this is a one of main goals, there are a lot of work but it under active development.
These are just examples but the key is that imperative api in core is a poison which will be creep into users’ projects if we’ll suggest them new ways to do that. We acknowledge that effector can be used in many ways and provide a ways to do something special: for example store.getState will silently switch to scope.getState(store) when it called in scope, so you don’t have to think how are you supposed to do imperative store reading from scopes, it’s just work. But the idea that we shouldn’t make such things more accessible to users, especially if it can be easily solved by a single createEffect
call
We admit that you pushes effector to its boundaries so it’s amazing stress-test for it 😃 And if you come across something truly insurmountable, write to us and we’ll try to solve this problem together
from effector.
Note about why I do the way I do:
When I first discovered effector I bought ideas like:
- visualization of architecture/models
- declarative
- "you don't need DI with Scope API" / "easy testing"
After 1.5 years of usage I've come to conclusion what second point it just hard way to program. Because behind all that cool declarative API you always have imperative logic, so if you not developing library there is not so much benefit comparated to cost of developing and maintaining this kinds of solution.
Second thing about declarative logic (writing your conditions in samples) — it just a mess. Even when you have small team only filled with seniors we still can't figure out an easy way to change our logic. Tho we figure out how to scope things so we don't need to read full model if we need to make some change, now only a block with samples which represent behavior. Without scoping it just a meaningless big ball of mud sample
Also it real pain to decompose all of it properly so usually result look like: "put this 5 custom operators together to do basic thing"
Point is — describing logic with sample
just harder compared to class-methods or just functions
Third thing about declarative pain is debugging — you can't just add a console.log
, you need to rearange your code to be able to do so (Inspect API still a mess mostly with a meaningless info). I mention this point here #997. And when you need to log whole usecase (like 5-10 samples) in proper order it is very frustrating
Fourth thing would be pain/cost of onboarding new developers — my backend fullstack devs which were able to add full features to other product can't even do simple ones without week of understanding how to do it. Most pain for them is lack of proper debuging like ReduxDevtolls state tab, they can't put all stores into patronum.debug
to just figure out how system works and what data it has
Now about visualization. I bought this "feature" and I expected it be delivered, maybe not after a month, not after half of year, just the end 2024 would be fine by me. Last time I checked (in lastest talk) estimation is about 4 years from today — its like 2028!!!. This is just not acceptable with tradeoffs I accepted mentioned above
Scope API is cool tho, but its not a DI, not in my understanding of DI. It is just method injection, where every store/effect which we could "call" when we want to replace state/implementation. It may work for simple cases, but when you start to have 5+ dependecies(I mean instances of models not just stores or effects passed by config for factory) it just real pain to duplicate all of that and you need a conventions to export "just for mocking in tests" and boilerplate to mock this things as u can't change reference (when you need to create instance of other factory withing model)
I could be wrong here and where is no other way, but at this point its unknown so I'll try to find peace with the "other way"
So at the end you need to switch to something which removes that pain, like classes and reflect-metadata but you really can't because of next point
Covariant vs contrvariant(leaky abtraction). I write this using v22 of effector so it may impoved in v23+, but in current state you can't really do interface level of programing. A little change in parameter just blows entire type system because store.updates
is not compatible as its not presiselly match interface. So it just renders interface-level programming useless (at least I can't make it work)
Also point about interfaces — you can't really implement
them because effector pushes usage without classes, but with function-factories if you add more fields to interface it wouldn't compile. And you can't do multiple implements
So at the end of the day I found myself in:
- codebase which only I could contribute
- codebase which has technical complexicity without real benefits
- cost of change is unresonably high, because you need figure out samples (I mean its ok if it would be for complex logic but with simple ones it doesn't get better/simpler)
- no real way to devtool-it
- no real way to visualize it
So by switching to "imperative" I cover first three of this points.
I'm shocked about results of it as it uncovered a lot of cases where we had missing error handlers as devs coudn't get through tons of samples when they need to add just catch block with common handling.
Its now realy isolated, so you can easily add change without worrying about all posible cases where this event could've be called with all possible states, now it withing your usecase within specific effect.
Its really easy to add console.log
to understand which values are there. And I went even further and implement something similar to #977 out of the box, so its really trivial to debug with one paramether.
I on my way to to devtool-it as i require now to pass name
attribute, so I woudn't see in my state-tree some meaningless hashes
Visualizing could be neat but its not a game changer now (like for xState)
I still finding a way to do constuctor (async too) without classes and hope to find a solution, but I doesn't see how it would even work (as reflect-metadata woudn't really work without classes)
Now it looks a lot like redux listener-api
with a performance benefit over redux but without ecosystem around it
It doen't really make sence to keep it that way so in the future I probably would find some way to migrate to either Mobx or RTK because it "just better"/or have more tools which empovers me rather giving me hard time
from effector.
Related Issues (20)
- `allSettled` should not accept derived units HOT 1
- Unsubscribing a sample HOT 1
- What's the best way to `forward` return values from effects to other store? HOT 3
- Question about DI HOT 5
- Broken types for `createApi` HOT 1
- Проблема с извлечением типов HOT 1
- Deprecate `Domain` unit creator methods HOT 1
- [babel-plugin] Add an option to disable transforming `Domain` methods HOT 1
- store.map() and lastState HOT 2
- Name collision in `combine` with `domain` HOT 5
- [effector-react] Add 'use client' directive to gate as component HOT 1
- Merge `values` and `handlers` in `fork`
- Invalid types for `createEffect` and `attach` in factories with generics HOT 2
- Deprecate second argument in `createEvent` and `createEffect`
- createGate overload do not apply default state null
- TypeScript error using events inside subclasses with generics
- Deprecate `use.getCurrent` HOT 1
- Remove UMD build
- Do not return Store from sample
- Remove `setStoreName` HOT 2
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 effector.