React + Flux——将输入绑定到单个“模型”的嵌套组件

React + Flux - Binding nested components with inputs to a single "model"

本文关键字:模型 嵌套 单个 组件 Flux 输入 绑定 React      更新时间:2023-09-26

从Angular的角度来看,理解作用域以及指令/控制器如何与HTML交互,与我试图做的这个简单的例子相比,似乎是相当合乎逻辑的。

基本上,我有几个组件。

/** @jsx React.DOM */
var React = require('react');
var {TextInput} = require("./controls/TextInput.jsx");
var Group = React.createClass({
    render: function () {      
        console.log(this.props.formdata); // passed from parent
        return (
                 <fieldset className="">
                    <legend>My Field Group</legend>
                     {this.props.field.fields.map(function(fld, i) {                           
                     return (<div className="my-field">
                                <TextInput formdata={formdata} field={fld} />
                            </div>);
                 })}
             </fieldset>
        );
    }
});
exports.Group = Group;

我的TextInput是这样的:

** @jsx React.DOM */
var React = require('react');
var TextInput = React.createClass({
    render: function () {
       return (
         <div className="form-group">
           <label htmlFor={this._reactInternalInstance._rootNodeID+'_input'}>{this.props.field.label}</label>
           <input type="" className="form-control" id={this._reactInternalInstance._rootNodeID+'_input'} value={???} placeholder=""/>
         </div>
        );
    }
});
exports.TextInput = TextInput;

首先,我很确定我用_rootNodeId做什么可以更好,但还没有找到任何更好的例子。

我的主要问题是找出如何将文本框的值绑定到我的模型。

我也在"使用"Flux,并且有一个

var SomeStore = require('../stores/some-store');

var SomeActions = require('../actions/some-action');

对象,我可以用它来管理数据和调度事件。从本质上讲,我需要做的是,当一个子文本输入中的值发生变化时,我想处理这个变化,可能会改变模型中的其他一些值,并告诉受影响的控件/dom元素更新自己。

欢迎指教。

谢谢山姆

我假设您希望在不提交实际提交输入的情况下执行此操作。在React/Flux中,商店是最接近"模型"的东西。你需要构建你的Flux架构,这样你的React组件就能监听到存储的变化。例如,在您的TextInput组件中,我假设您不想实际提交数据(只需在输入信息后立即更新信息):

** @jsx React.DOM */
var React = require('react');
var SomeActions = require('../actions/some-action');
var TextInput = React.createClass({
    handleChange: function () {
        var generatedRef = this._reactInternalInstance._rootNodeID+'_input';
        var data = React.findDOMNode(this.refs[generatedRef]).value;
        SomeActions.UpdateStore(data);
    },
    render: function () {
        var generatedRef = this._reactInternalInstance._rootNodeID+'_input';
        return (
            <div className="form-group">
                <label htmlFor={this._reactInternalInstance._rootNodeID+'_input'}>{this.props.field.label}</label>
                <input type="text" ref={generatedRef} onChange={this.handleChange} className="form-control" id={this._reactInternalInstance._rootNodeID+'_input'} placeholder=""/>
            </div>
        );
    }
});
exports.TextInput = TextInput;

声明generatedRef不是必要的,但我这样做是为了清楚。在SomeActions中,您需要通过调度器调度有效载荷。SomeStore需要侦听这种类型的有效负载并相应地更新其数据,然后发出其他组件正在侦听的更改。例如:

/** @jsx React.DOM */
var React = require('react');
var {TextInput} = require("./controls/TextInput.jsx");
var SomeStore = require('../stores/some-store');

var getData = function () {
    return SomeStore.retrieveData(); //should return an object 
};
var Group = React.createClass({
    onChange: {
    this.setState(getData());
    },
    componentDidMount: {
        SomeStore.addChangeListener(this.onChange);
    },
    componentWillUnmount: {
        SomeStore.removeChangeListener(this.onChange);
    },
    render: function () {      
        console.log(this.props.formdata); // passed from parent
        return (
            <fieldset className="">
                <legend>My Field Group</legend>
                 {this.props.field.fields.map(function(fld, i) {                           
                 return (
                     <div className="my-field">
                         <TextInput formdata={formdata} field={fld} />
                     </div>);
                })}
            </fieldset>
        );
    }
});
exports.Group = Group;

这是我能做的最好的不知道你的动作和存储看起来像什么。基本上,只要您更改输入字段中的数据,handleChange就会调度一个操作。此操作将更新存储。store应该在更新时发出一个change事件。然后,侦听这些更改的任何组件都将相应地更新,以反映商店的当前数据。