我在很多教程中都看到React拥有单向数据流,是否有可能在reactjs中实现双向数据流?
答案 0 :(得分:0)
让我们以一个类组件为例。内置的反应输入组件的API如下:
class Demo extends React.Component {
state = { value: "foobar" }
render() {
return (
<input
value={this.state.value}
onChange={event => this.setState({ value: event.target.value })}
/>
)
}
}
我们可以在一个自定义组件的基础上构建,该组件具有类似于双向组件的API:
<Input model={state} propName="value" />
方法如下:
function Input(props) {
const { model, propName } = props
return <input
value={model[propName]}
onChange={event => model[propName] = event.target.value}
/>
}
坏消息是,仅此组件是无法实现魔力的,我们需要消费者方面的一些努力。
让我们制作一个类属性装饰器来投射魔法。
function bidirectional(target, key) {
Object.defineProperty(target, key, {
get() {
return this.state['__' + key]
},
set(val: any) {
const privateKey = '__' + key
if (!this.state) this.state = {}
if (this.state.hasOwnProperty(privateKey)) {
this.setState({ [privateKey]: val })
} else {
this.state[privateKey] = val
}
return true
}
})
}
现在您可以这样做:
class Demo extends React.Component {
@bidirectional
value = "foobar"
render() {
return (
<Input model={this} propName="value" />
)
}
}
直接设置this.value = "whatever"
也可以,就像大多数双向绑定视图模型一样。
我个人是单向的。并不是说双向是错误的,而是像大多数人所说的那样,以单向的方式思考确实可以在大多数时间获得回报,可以帮助您清楚地了解应用程序。
如果我认为合适,我会不时切换到双向范例。就像评论中提到的那样,MobX.js是一个出色的库,它扩展了双向想法的方式,并且在反应方面也非常有效。您应该调查一下。