Skip to content
This repository has been archived by the owner on Dec 31, 2020. It is now read-only.

Commit

Permalink
Clarify the reason why there is the restriction on changing the set o…
Browse files Browse the repository at this point in the history
…f stores (#760)

* Clarify the reason why there is the restriction on changing the set of stores

Fixes #745

* Update README.md

Co-Authored-By: Daniel K. <FredyC@users.noreply.github.com>
  • Loading branch information
vkrol and FredyC committed Aug 12, 2019
1 parent a253be5 commit 34ab6ef
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 5 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,13 @@ Notes:

- It is possible to read the stores provided by `Provider` using `React.useContext`, by using the `MobXProviderContext` context that can be imported from `mobx-react`.
- If a component asks for a store and receives a store via a property with the same name, the property takes precedence. Use this to your advantage when testing!
- Values provided through `Provider` should be final. Make sure that if you put things in `context` that might change over time, that they are `@observable` or provide some other means to listen to changes, like callbacks. However, if your stores will change over time, like an observable value of another store, MobX will throw an error.
- When using both `@inject` and `@observer`, make sure to apply them in the correct order: `observer` should be the inner decorator, `inject` the outer. There might be additional decorators in between.
- The original component wrapped by `inject` is available as the `wrappedComponent` property of the created higher order component.

#### "The set of provided stores has changed" error
Values provided through `Provider` should be final. Make sure that if you put things in `context` that might change over time, that they are `@observable` or provide some other means to listen to changes, like callbacks. However, if your stores will change over time, like an observable value of another store, MobX will throw an error.
This restriction exists mainly for legacy reasons. If you have a scenario where you need to modify the set of stores, please leave a comment about it in this issue https://github.com/mobxjs/mobx-react/issues/745. Or a preferred way is to [use React Context](https://mobx-react.js.org/recipes-context) directly which does not have this restriction.

#### Inject as function

The above example in ES5 would start like:
Expand Down
2 changes: 1 addition & 1 deletion src/Provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function Provider({ children, ...stores }) {
const newValue = { ...value, ...stores } // spread in previous state for the context based stores
if (!shallowEqual(value, newValue)) {
throw new Error(
"MobX Provider: The set of provided stores has changed. Please avoid changing stores as the change might not propagate to all children"
"MobX Provider: The set of provided stores has changed. See: https://github.com/mobxjs/mobx-react#the-set-of-provided-stores-has-changed-error."
)
}
}
Expand Down
4 changes: 1 addition & 3 deletions test/Provider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ describe("Provider", () => {
withConsole(() => {
expect(() => {
rerender(<A foo={2} />)
}).toThrow(
"The set of provided stores has changed. Please avoid changing stores as the change might not propagate to all children"
)
}).toThrow("The set of provided stores has changed.")
})
})
})

0 comments on commit 34ab6ef

Please sign in to comment.