当前位置: 首页 > 知识库问答 >
问题:

将新的服务器数据传递给react.js组件

黎阳冰
2023-03-14

我是新来的。js,并努力理解一些核心概念,以决定是否将此库用于我们的应用程序。我的主要问题实际上是在从服务器获取的模型中处理更新。

想象一下,我有一个页面应该显示五个不同的模型。我已经按照本文中描述的方式构建了它:http://facebook.github.io/react/blog/2013/11/05/thinking-in-react.html,所以我有“根”组件,所有5个模型都通过了这个组件,并且使用道具,它们将下降到持有这个模型的组件。所以,现在更新了2个模型(我从我的模型代码中获得了这个事件,它生活在反应组件之外),我需要在用户界面上反映这一点。最好的方法是什么?

我正在考虑以下选择:

  1. 再次使用新数据运行renderComponent,并依赖DOM diff react技术。我对此有点担心,因为我需要对任何微小的数据更改执行此操作

提前谢谢你,希望我能清楚地解释我的问题。

共有3个答案

穆英飙
2023-03-14

目前,我至少知道三种向组件传递新数据的方法:

  1. 重新渲染组件。不要担心这种方法的效率,因为React似乎处理得很好。关于这方面有很多不错的文章:JavaScript框架中的更改及其检测,以及使用React进行更新。渲染

对于第三个选项,我受到史蒂文的启发,并将其扩展了一点。请在jsfiddle.net/kb3gN/12002/.检查我的实现

var Data = { value: 1 };

var dataChange = function(callback){
    if(callback){
        callback(Data);
        setInterval(function(){
            Data.value++;
            callback(Data);
        }, 1000);
    }
    return Data;
};

var World = React.createClass({
    render: function() {
        return <strong>{this.props.data.value}</strong>;
    }
});

var Hello = React.createClass({
    getInitialState: function() {
        return {
          data: this.props.dataChange()
        };
    },
    componentDidMount: function() {
        this.props.dataChange(this.updateHandler)
    },
    updateHandler: function(data) {
        this.setState({
          data: data
        });
    },
    render: function() {
        return (
            <div>
                Value: <World data={this.state.data} />
            </div>
        );
    }
});

React.renderComponent(<Hello dataChange={dataChange} />, document.body);

JSFIDLE上还有一个扩展版本。net/kb3gN/12007。

function ListenersService(){
    var listeners = {};
    this.addListener = function(callback){
        var id;
        if(typeof callback === 'function'){
            id = Math.random().toString(36).slice(2);
            listeners[id] = callback;
        }
        return id;
    }
    this.removeListener = function( id){
        if(listeners[id]){
            delete listeners[id];
            return true;
        }
        return false;
    }
    this.notifyListeners = function(data){
        for (var id in listeners) {
          if(listeners.hasOwnProperty(id)){
            listeners[id](data);
          }
        }
    }
}

function DataService(ListenersService){
    var Data = { value: 1 };
    var self = this;

    var listenersService = new ListenersService();
    this.addListener = listenersService.addListener;
    this.removeListener = listenersService.removeListener;
    this.getData = function(){
        return Data;
    }

    setInterval(function(){
        Data.value++;
        listenersService.notifyListeners(Data);
    }, 1000);
}
var dataSevice = new DataService(ListenersService);

var World = React.createClass({
    render: function() {
        return <strong>{this.props.data.value}</strong>;
    }
});

var Hello = React.createClass({
    getInitialState: function() {
        return {
          data: this.props.dataService.getData()
        };
    },
    componentDidMount: function() {
        this.props.dataService.addListener(this.updateHandler)
    },
    updateHandler: function(data) {
        this.setState({
          data: data
        });
    },
    render: function() {
        return (
            <div>
                Value: <World data={this.state.data} />
            </div>
        );
    }
});

React.renderComponent(<Hello dataService={dataSevice} />, document.body);

此实现并不完全遵循独立组件的思想(因为Hello组件依赖于DataServiceAPI),但它可以进一步抽象,并取决于应用程序开发人员其组件将遵循哪些特定于应用程序的约定。例如,请参阅JSFIDLE上第一个和第二个示例的混合。net/kb3gN/12015(HallodatAtic对象和HallodatDynamic回调)

注意:示例中使用的ListenersService遵循Observer模式,并且该模式本身在许多场景中弊大于利。但除此之外,我想通过这些示例说明的是,有一种通过回调进行数据绑定的方法

<div id="static"></div>
<div id="dynamic"></div>
<script>

function ListenersService(){
    var listeners = {};
    this.addListener = function(callback){
        var id;
        if(typeof callback === 'function'){
            id = Math.random().toString(36).slice(2);
            listeners[id] = callback;
        }
        return id;
    }
    this.removeListener = function( id){
        if(listeners[id]){
            delete listeners[id];
            return true;
        }
        return false;
    }
    this.notifyListeners = function(data){
        for (var id in listeners) {
          if(listeners.hasOwnProperty(id)){
            listeners[id](data);
          }
        }
    }
}

function DataService(ListenersService){
    var Data = { value: 1 };
    var self = this;

    var listenersService = new ListenersService();
    this.addListener = listenersService.addListener;
    this.removeListener = listenersService.removeListener;
    this.getData = function(){
        return Data;
    }

    setInterval(function(){
        Data.value++;
        listenersService.notifyListeners(Data);
    }, 100);
}
var dataSevice = new DataService(ListenersService);
var halloDataDynamic = function(callback){
    var data = dataSevice.getData();
    if(callback){
        dataSevice.addListener(function(data){
            callback(data);
        });
    }
    return data;
};
var halloDataStatic = dataSevice.getData();

var World = React.createClass({
    render: function() {
        return <strong>{this.props.data.value}</strong>;
    }
});

var Hello = React.createClass({
    getInitialState: function() {
        var data;
        if(typeof this.props.halloData === 'function'){
            data = this.props.halloData(this.updateHandler)
        }
        else data = this.props.halloData;
        return {
          data: data
        };
    },
    updateHandler: function(data) {
        this.setState({
          data: data
        });
    },
    render: function() {
        return (
            <div>
                Value {this.props.name}: <World data={this.state.data} />
            </div>
        );
    }
});
</script>

React.renderComponent(<Hello halloData={halloDataStatic} name="static"/>, document.getElementById('static'));
React.renderComponent(<Hello halloData={halloDataDynamic} name="dynamic"/>, document.getElementById('dynamic'));
岳彬炳
2023-03-14

如果将数据作为道具向下传递给子组件,则只需在更高级别上更新它,它将强制对使用相同属性html" target="_blank">对象的所有组件进行渲染。考虑这个简单的例子:

var World = React.createClass({
    render: function() {
        return <strong>{this.props.name}</strong>;
    }
});

var Hello = React.createClass({
    clickHandler: function() {
        this.setProps({ name: 'earth' });
    },
    render: function() {
        return (
            <div>
                Hello <World name={this.props.name} />
                <button onClick={this.clickHandler}>Click me</button>
            </div>
        );
    }
});

现在,当用户单击按钮时,您更改了Hello组件上的属性,但是由于您将相同的属性(或数据)对象传递给了子对象,因此子对象将对此做出反应并相应地更新其阴影DOM。

以下是我的意思:http://jsfiddle.net/xkCKR/

如果您有一个外部数据对象,您可以将它传递给顶部组件。请记住,这并不意味着有双向绑定:

// simple example of a data model
var Data = { name: 'world' };

var World = React.createClass({
    render: function() {
        return <strong>{this.props.data.name}</strong>;
    }
});

var Hello = React.createClass({
    clickHandler: function() {
        this.setProps({
            data: { name: 'earth' }
        });
    },
    render: function() {
        return (
            <div>
                Hello <World data={this.props.data} />
                <button onClick={this.clickHandler}>Click me</button>
            </div>
        );
    }
});

React.renderComponent(<Hello data={Data} />, document.body);

这是有效的,因为反应使用属性的单向绑定。但是如果说你的子组件会更新它的属性,它就不会爬到它的父组件。为此,您需要ReactLink加载项或使用像Backbone提供的pub/sub接口。

郏志学
2023-03-14

使用相同的组件但不同的数据再次调用renderComponent等同于调用组件。setProps()。因此,要么以最小公分母将所有模型保持为状态,要么在更改时再次调用setProps/renderComponent。

 类似资料:
  • 我有三节课 1.菜单活动 2.LocationUpdateService 3.多重标记器 1.菜单活动 2、LocationUpdateService:(这是服务类) 3、多重标记(活动) 我的问题是:当我打开我的菜单活动我的Toast消息打印发送数据到广播接收器,然后点击按钮我调用MultipleMarker。我无法从服务中获取值。。。但当我按下后退按钮时,我重定向到MenuActivity,此

  • 问题内容: 我想将回调传递给加倍嵌套的组件,并且尽管我能够有效地传递属性,但我不知道如何将回调绑定到正确的组件上才能被触发。我的结构如下所示: 单击列表项时应触发一个回调,这是OutermostComponents方法“ onUserInput”,但相反,我得到“未捕获的错误:未定义不是函数”。我怀疑问题出在我如何在第一个内部渲染SecondNestedComponent并将其传递给回调函数。代码

  • 也许有一种方法可以将组件绑定到事件? 在使用React一年多后,在Sebastien Lorber的回答的激励下,我得出结论,将子组件作为参数传递给父母中的函数实际上不是React的方式,也不是一个好主意。我换了答案。

  • 问题内容: 我想将由Razor MVC帮助程序在我的登录表单中生成的RequestVerificationToken传递给我为管理应用程序身份验证而完成的AngularJS服务 我的形式如下: @ Html.AntiForgeryToken()以这种方式呈现: 我的AngujarJs控制器成功注入了我的“ loginService”,我可以通过Post发送用户名和密码到服务 服务: 我的问题是如何

  • 但是这不起作用,因为上下文是在所有解析器之间共享的,因此如果我在查询上有多个,上下文值就不好。 我还尝试在嵌套解析器上使用上可用的。我可以转到字段,但这里没有参数... 我还尝试在上添加一些数据,但这些数据不在嵌套解析器上共享。