I've been seeing an issue in mobx-react with bootstrap-4 and I'm getting some unexpected results that is driving me crazy. I've boiled it down to the simple example below.
1) Model object that simply holds an array of data. And an action that provides a way to add data to the array.
2) App component that instantiates the model object and will render:
- the model's
datawhich is an array rendered as JSON string (that data is marked asobservable). - A button to add a new object to model (the add is marked as an
actionin the model object) All this works fine, if I don't wrap theButtonin a bootstrap4Form, like below:
render() {
return (
<>
{JSON.stringify(this.model.data)}
<Button onClick={this.addNewItem}>Add Another</Button>
</>
)
}
But if the Button is wrapped in a bootstrap4 Form, you can see a slight delay where the JSON is changed to include the new item, but then instantly reverts back to the old data which does not include the new item.
render() {
return (
<>
{JSON.stringify(this.model.data)}
<Form>
<Button onClick={this.addNewItem}>Add Another</Button>
</Form>
</>
)
}
Any idea what might be going on here? Full Source is below.
Thanks,
Chris
import React, { Component } from 'react';
import { observer } from 'mobx-react'
import { Card, Form, Button } from 'bootstrap-4-react';
import { action, makeObservable, observable } from 'mobx';
class Model {
data = null
constructor(data) {
this.data = data
makeObservable(this, {
data: observable,
add: action
})
}
add() {
this.data.push({ "Date": new Date() })
}
}
class App extends Component {
constructor(props) {
super(props)
this.addNewItem = this.addNewItem.bind(this);
var data = [
{
"Date": new Date()
}
]
this.model = new Model(data)
}
addNewItem() {
this.model.add()
}
render() {
return (
<>
{JSON.stringify(this.model.data)}
<Form>
<Button onClick={this.addNewItem}>Add Another</Button>
</Form>
</>
)
}
}
export default observer(App);
Top comments (1)
Response from github.com/mobxjs/mobx/discussions...
Hi, it's not related to Mobx. If you don't provide action attribute on a form, it sends the data to current URL thus reloading page: developer.mozilla.org/en-US/docs/L...
"If this attribute isn't provided, the data will be sent to the URL of the page containing the form — the current page."
You can fix it by providing onSubmit attribute to prevent form submitting:
<Form onSubmit={(e) => { e.preventDefault() }}><Button onClick={this.addNewItem}>Add Another</Button>
</Form>
Here is a working example:
codesandbox.io/s/adoring-sky-xrwbp...