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
data
which 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
action
in the model object) All this works fine, if I don't wrap theButton
in 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...