Β
const UserCard = ({ user }) => (
<div>
<p> Name: {user.name} </p>
<p> Age: {user.age} </p>
</div>
)
class UserPage extends Component {
userData = {}
componentDidMount() {
// Fetch information of current user
fetch('https://restful-api-endpoint.com/v1/user/30678')
.then(res => res.json())
.then(json => this.setState({ userData: json }))
}
render() {
return (
<>
<UserCard user={this.state.userData} />
</>
)
}
}
A simple but usual case:
Developing a SPA and handle routes by react router.
class AboutMePage extends Component {
render() {
const { userData } = this.state
return (
<>
Welcome {userData.name}! Check your information below.
<UserCard user={userData} />
</>
)
}
}
const Sidebar = ({ user }) => (
<>
<Header user={user} />
<Menu>
<MenuItem>Homepage</MenuItem>
<MenuItem>About Me</MenuItem>
<MenuItem>Posts</MenuItem>
</Menu>
</>
)
const Header = ({ user }) => (
<UserCard user={userData} />
)
Imagine that we have to display UserCard UI with the shared data otherwhere.
class AppRoot extends Component {
userData = {}
componentDidMount() {
// Fetch information of current user
fetch('https://restful-api-endpoint.com/v1/user/30678')
.then(res => res.json())
.then(json => this.setState({ userData: json }))
}
render() {
const { userData } = this.state
return (
<BrowserRouter>
<Sidebar user={userData} />
<Switch>
<Route
path="/about"
render={routeProps => <AboutMePage {...routeProps} user={userData} />}
/>
<Route
path="/user"
render={routeProps => <UserPage {...routeProps} user={userData} />}
/>
</Switch>
</Router>
)
}
}
There is a simple and intuitive solution.
https://www.carlrippon.com/playing-with-the-context-api-in-react-16-3/
https://itnext.io/integrating-semantic-ui-modal-with-redux-4df36abb755c
import { observable } from 'mobx'
const state = {
userData: {},
}
export default observable(state)
import { observer } from 'mobx-react'
import UserCard from '../components/UserCard'
import state from './state'
const Comp = () => (
<>
<UserCard user={state.data} />
</>
)
export default observer(Comp)
class TodoList {
@observable todos = []
@computed get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length
}
}
import { decorate, observable } from "mobx"
class TodoList {
todos = []
get unfinishedTodoCount() {
return this.todos.filter(todo => !todo.finished).length
}
}
decorate(TodoList, {
todos: observable,
unfinishedTodoCount: computed
})
@observer
class TodoListPage extends Component {
const { store } = this.props
render() {
return (
<div>
<ul>
{
store.todos.map(todo => <TodoItem todo={todo} key={todo.id} />)
}
</ul>
Tasks left: {store.todos.unfinishedTodoCount}
</div>
)
}
}
const TodoItem = observer(({ todo }) =>
<li>
<input
type="checkbox"
checked={todo.finished}
onClick={() => todo.finished = !todo.finished}
/>
{todo.title}
</li>
)
const store = new TodoList()
ReactDOM.render(<TodoListPage store={store} />, document.getElementById('app'))
Unlike many flux frameworks, MobX is unopinionated about how user events should be handled.
This can be done in a Flux like manner.
Or by processing events using RxJS.
Or by simply handling events in the most straightforward way possible, as demonstrated in the above onClick handler.
There is no technical need for firing events, calling a dispatcher or what more. A React component in the end is nothing more than a fancy representation of your state. A derivation that will be managed by MobX.
import { action, observable } from 'mobx'
const state = {
userData: {},
getUserData: action(function() {
fetch('https://restful-api-endpoint.com/v1/user/30678')
.then(res => {
this.userData = res
})
})
}
export default observable(state)
Single store (SSOT)
FP paradigm
Pure
Explicit update logic and dataflow
More boilerplate
Normalized state
Multiple stores
RFP paradigms
Impure
Implicit update logic and dataflow
Less boilerplate
Denormalized state
Redux | MobX | |
---|---|---|
Easy to learn | π | πππ |
Scalability | πππ | ππ |
Testability | πππ | π |
Predictability | πππ | ππ |
Line of code | π | πππ |
Managing Asynchronous Calls | β | β |
Handling Side Effects | β | β |
βSeparation of Concerns (SoC) | β | β |