Closed demux closed 8 years ago
Hello @demux. Indeed, I decided not to provide cursors through context anymore because I believe this is kind of a bad practice to do so. You should rely on actions instead if what you want is to edit the tree. Alternatively, you can still access the tree through context if you ever need it. What's more, this should provide some performance benefits not to pass the cursors.
I solved my problem by using dispatch on an instance method. Creating an action for setting any path in the tree seemed kinda bonkers.
import React, {Component} from 'react'
import {branch} from 'baobab-react/higher-order'
import PropTypes from 'baobab-react/prop-types'
import Textarea from 'react-textarea-autosize'
export class BaseBoundInput extends Component {
constructor(props) {
super(props)
this._setValue = this._setValue.bind(this)
this.setValue = this.setValue.bind(this)
this.onChange = this.onChange.bind(this)
}
// componentDidUpdate() {
// console.log(`BoundInput [${this.getFullPath().join(', ')}] Updated`)
// }
onChange(e) {
this.setValue(e.target.value)
}
setValue(value) {
this.props.dispatch(this._setValue, value)
}
_setValue(tree, value) {
tree.select(this.getFullPath()).set(value)
tree.commit()
}
getFullPath() {
return (this.props.basePath || []).concat(this.props.path || [])
}
inputProps() {
const {value, type, ...props} = this.props
return {
type: (type && type !== 'textarea') ? type : 'text',
name: this.getFullPath().join('.'),
value: value || '',
onChange: this.onChange,
...props
}
}
renderInput() {
return this.props.type === 'textarea'
? <Textarea {...this.inputProps()} />
: <input {...this.inputProps()} />
}
render() {
const {label} = this.props
if(label === undefined) {
return this.renderInput()
}
return <div className="field">
<label>{label}</label>
{this.renderInput()}
</div>
}
}
export const curriedBranch = branch((props) => {
return {
value: BaseBoundInput.prototype.getFullPath.call({props})
}
})
const BoundInput = curriedBranch(BaseBoundInput)
export default BoundInput
It may seem overkill to use actions but every recent state management option with React do so to keep a sane architecture (Flux & redux notably). People like to centralize in their own files all the modification logic of the state rather than having to find the related components.
I use actions for everything else, but in this case it would kinda be like going home from work to get sunglasses just to cross the street.
In this particular case, I usually tend to use function composition either at component or action level not to have to write this every time.
I noticed that in higher-order.js cursors are no longer provided in context. What is the proposed alternative?