如何在服务器端React组件中使用回调值?

时间:2016-04-05 19:37:43

标签: javascript node.js mongodb reactjs callback

我在使用服务器端React显示Mongo数据库中的播放器列表时遇到了问题。

我的目标是 NOT 使用除mongodbreact之外的外部库,因为在开始实施高级解决方案之前,我想学习基础概念。

我的代码需要一个模块(players.js)并调用index.jsx中定义的应该处理Mongo查询结果的回调。组件可以访问这些过程结果。

这是:

players.js

var MongoClient = require('mongodb').MongoClient;

var url = 'mongodb://localhost/collection';
var database;
var players;

module.exports = function(callback) {

    // Initialize collection
    MongoClient.connect(url, function(err, db) {
        database = db;
        database.collection('players', findPlayers);
    });

    // This named callback function is here in case
    // I want to do anything else with the collection
    function findPlayers(err, collection) {
        collection.find({}, getCursor);
    }

    function getCursor(err, cursor) {
        cursor.toArray(function(err, players) {
            // Invoke callback with err and players array
            callback(err, players);

            // Close Mongo connection
            database.close();   
        });
    }
}

index.jsx

var React = require('react');
var players = require('./players');

// call module and pass processPlayers function
var competitors = players(processPlayers);

// with the query results, return some neat JSX code
function processPlayers(err, results) {
    return results.map(function(player) {
        return (
            <tr>
                <td>{ player.rank }</td>
                <td>{ player.name }</td>
            </tr>
        )
    });
}

// Create index component class
var Index = React.createClass({
    render: function() {
        return ( <main><table>{ competitors }</table></main> );
    }
});

// Export component
module.exports = Index;

我理解在index.jsx我将competitors设置为未定义的回报,但那是因为我被卡住了。如何将competitors设置为映射结果?

同样,我 NOT 正在寻找承诺或异步库。 我想学习基础知识和正确的代码结构。我很高兴看到相关的库源代码(如果提供的话)。

谢谢!

1 个答案:

答案 0 :(得分:0)

我发布了我的问题的答案。

可以找到我用于服务器端版React的库here

在文档中,我发现.jsx视图是同步的,建议我在路由中传递数据库查询结果。此数据将通过this.props在组件中公开为属性。

所以...我进入了我的路线文件并更改了原始代码:

module.exports = function (req, res) {
    res.render('index');
}

对此:

var players = require('../helpers/players');

module.exports = function (req, res) {
    // call to module with anonymous function callback
    players(function(err, results) {
        if (err) return console.log(err);
        // using arg from anonymous function and
        // passing as local variable
        res.render('index', {'players': results});
    })
};

现在我的组件渲染方法看起来像这样......

render: function() {

    function createPlayerRows(player) {
        return (
            <tr>
                <td>{ player.rank }</td>
                <td>{ player.name }</td>
            </tr>           
        );
    }

    // `players` property provided by route
    // mapped array using callback function which
    // creates an array of JSX elements
    var players = this.props.players.map(createPlayerRows);

    return ( <main><table>{ players }</table></main> );
}

不确定是否会帮助任何人,但我确信松了一口气。