-
-
Notifications
You must be signed in to change notification settings - Fork 222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutating store state directly #1032
Comments
Yes, mutating store value definitely will become a problem. In the documentation this is pointed out several times: https://effector.dev/en/api/effector/store/
https://effector.dev/en/api/effector/store/#on-triggers-reducer
https://effector.dev/en/explanation/glossary/#reducer
There are few options here, but let me ask, do you have any performance issues with it, or are you just asking out of curiosity? If this is the first case, it is better to prepare an example repo with an issue. Otherwise there is no real use of such "what if's". And better place for such questions is in our community chats, than in github issues. |
I asked because I have a scrollable list of messages, where each message has a clickable "header" if it quotes another message. You can click on the header and it will scroll to that quoted message. In addition, my backend can return a message ID to an effect. I I can write out some sample code if I didn't explain it well. The idea is that I need access to the list node and its attributes such as But I guess a workaround would be to have another state variable like,
Then I'd set its value with the message ID that comes from the backend, and somewhere in a |
You could put your value into a "box" and recreate this box when you do some mutation, so instead of copying your big array all you have to do is create new box This could look something like this: const $hugeList = createStore({ list: [] })
.on(getData.doneData, (_, dateFromBackend) => ({ list: dataFromBackend }))
.on(addNewItemToList, (current, newItem) => {
const { list } = current;
list.push(newItem);
return { list }
}) This solution has some tradeoffs tho. You can't create computed stores with direct reference to Example: // bad, because `$fromToday` wouldn't be updated when `addNewItemToList` is called,
// because $list references same object thus stops update propagation
const $list = $hugeList.map(box => box.list);
const $fromToday = $list.map(list => list.filter(item => item.createdAt > startOfToday())
// good, because it depends on reference check for `$hugeList` "box"
// so when `addNewItemToList` creates new reference `$fromToday` is updatedProperly
const $fromToday = $hugeList.map(box => box.list.filter(item => item.createdAt > startOfToday())) P.S. Array.prototype.filter is O(n) and if you have huge n-s you probably should avoid this, but example is here for the sake of simplicity |
Suppose the following:
Could this become a problem if I decide to mutate this state as I did in the above code snippet?
Right now, I am doing something like this:
I ask, because direct mutation of state in other state managers (and even in React itself) goes against best practices.
If I cannot/should not mutate state directly, then what are my options here? What if
$store.length === 1e6
and I need to frequently do some operations on it?Another use case.
The text was updated successfully, but these errors were encountered: