If you know all the keys that the model will have, you can just initialize them with a null value, and the observer components will re-render.
Example (JSBin)
class BaseStore {
@observable model = {
type: null
};
@action updateStore(propertyName, newValue) {
this.model[propertyName] = newValue;
}
}
const baseStore = new BaseStore();
@observer
class App extends Component {
componentDidMount() {
setTimeout(() => baseStore.model.type = 'CreditCard', 2000);
}
render() {
return <div> { baseStore.model.type } </div>;
}
}
If you don't know all the keys of model beforehand, you can use a map like you said:
Example (JSBin)
class BaseStore {
model = observable.map({});
@action updateStore(propertyName, newValue) {
this.model.set(propertyName, newValue);
}
}
const baseStore = new BaseStore();
@observer
class App extends Component {
componentDidMount() {
this.interval = setInterval(() => {
const key = Math.random().toString(36).substring(7);
const val = Math.random().toString(36).substring(7);
baseStore.updateStore(key, val);
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <div>
{ baseStore.model.entries().map(e => <div> {`${e[0]} ${e[1]}` } </div>) }
</div>;
}
}