-
-
Notifications
You must be signed in to change notification settings - Fork 348
Observable props of @observer-ed component #124
Comments
Yeah I definitely see why you want this :) I can see three options
|
|
just took a shot at this one, by trying to make the An alternative |
cool, just figured out how to do this properly! Can be tried with build: |
@mweststrate thank you for investigation on this! |
As an alternative to this approach, I've been using the following simple utility in my own code: function mobxWrap<M>(Wrapped: React.ComponentClass<M> | React.SFC<M>) {
@observer
class MobxWrapper extends React.Component<{ model: M }, void> {
render() {
return <Wrapped {...this.props.model} />
}
}
return MobxWrapper
} Which can be used like so: type Person = { firstName: string, lastName: string }
// Wrap a stateless component -- pure simplicity!
const Stateless = mobxWrap(({ firstName, lastName }) => (
<h2>Hello, {firstName} {lastName}!</h2>
))
// Wrap a stateful component
@observer
class Greeting extends React.Component<PatientHeader, void> {
@observable private age: number = 0
constructor() {
super()
setInterval(() => { this.age++ }, 1000)
}
render() {
return (
<div>
<h2>Hello, {this.props.firstName} {this.props.lastName}!</h2>
You are {this.age} seconds old!
</div>
)
}
}
const Stateful = mobxWrap(Greeting) I was considering making a microlibrary for this function, but thought I'd propose incorporating it into the |
Until such time as props themselves can be observable, I've made a library for the above utility: |
Never mind, I just discovered this approach has the flaw that |
@pelotom could you please try use |
Hm, it doesn't seem to work for me. Here's my test: import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { observable, computed } from 'mobx'
import { observer } from 'mobx-react'
class Props {
@observable x: number = 0
@computed get y() { return this.x + 1 }
}
@observer
class Component extends React.Component<Props, void> {
render() { return <div>x={this.props.x}, y={this.props.y}</div> }
}
const props = new Props()
ReactDOM.render(<Component {...props} />, document.getElementById('root'))
// Should render: <div>x=0, y=1</div>
// Actually renders: <div>x=0, y=</div>
props.x++
// Should render: <div>x=1, y=2</div>
// Doesn't re-render |
@pelotom thank you for feedback. |
Ah, then I've misunderstood the point of this issue. I thought the point was to make it so we didn't have to wrap observables in a prop, but could pass an object with observable fields as the entire set of props. That's what I'm trying to do with https://github.com/pelotom/mobx-component. |
@pelotom unfortunatelly, I think it is not possible to do without wrapper (as you suggested), or without some code transformation (such as a babel plugin). Btw, by default, babel converts |
Well good, I guess I didn't waste all my time making that :) |
Can be tested with |
Shipped with 4.0.0 :) |
@mweststrate What specifically shipped with 4.0? Can we make Specifically, I want to pass an observable down from a HOC, which I presently can't seem to do without putting it in a prop and boxing it. |
@mnpenner mobx-react@4 was released in 2016 |
As for now,
this.props
object itself is not an observable, which is a problem if we trying to use it insidecomputed
function or bount child component. Some examples:claculatedValue
does not tracksthis.props
properties, because it is not reactive. And the developer ran into unobviously issue, "why mu computed function does not recompute?"Second one is bit more complex, but has almost same behaviour:
If
Component
receives new proponChildClick
, this function is not assigned to child div, because child component does not rerender.As for now, I'm working on custom decorator, which made
this.props
of component observable. I'll show you my results, and we'll have a little discuss about it :)The text was updated successfully, but these errors were encountered: