繁体   English   中英

子组件更改时刷新应用状态

[英]Refreshing App State on Child Component Change

我有一个元素列表。 当我单击向上或向下图标时,我希望列表重新排列,并最终使应用程序重新呈现,这样我就可以看到DOM中反映的更改。

更改列表位置是可行的。 尝试运行refreshState方法时遇到问题。 我将函数作为子项的属性传递,但调用该属性将返回未定义的函数。

问:如何从子组件中调用组件的方法?

码:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <script src="http://fb.me/react-with-addons-0.12.2.js"></script>
    <script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
</head>
<body>
    <style>
        /* CSS */
        span {
            margin:0 0 0 10px;
        }
    </style>
    <div id="app"></div>
    <script type="text/jsx">
        // React

        var _data = ['Red', 'Blue', 'Green'];


        function getState() {
            return {
                colors: _data,
            }
        };


        Array.prototype.swap = function(a, b) {
            var temp = this[a];
            this[a] = this[b];
            this[b] = temp;
        };


        var App = React.createClass({

            getInitialState: function() {
                return getState();
            },

            render: function() {
                var colors = this.state.colors.map(function(color) {
                    return (
                        <Color name={color} refreshState={this.refreshState} />
                    )
                });
                return (
                    <ul>{colors}</ul>
                )
            },

            refreshState: function() {
                return this.setState(getState());
            },

        });


        var Color = React.createClass({

            moveUp: function() {
                var current = _data.indexOf(this.props.name),
                    above = current - 1;

                if (above >= 0) {
                    _data.swap(current, above);
                }

                return this.props.refreshState();
            },

            moveDown: function() {
                var current = _data.indexOf(this.props.name),
                    below = current + 1;

                if (below < _data.length) {
                    _data.swap(current, below);
                }

                return this.props.refreshState();
            },

            render: function() {
                return (
                    <li>
                        <strong>{this.props.name}</strong>
                        <span onClick={this.moveUp}>^</span> 
                        <span onClick={this.moveDown}>v</span>
                    </li>
                )
            },

        });


        React.render(<App />, document.getElementById('app'));
    </script>
</body>
</html>

注意到您已经解决了问题,但是我想提到您可以将范围传递给.map,这意味着无需出于描述的目的缓存范围:

this.state.colors.map(function(color) {
    return (
        <Color 
            key={_data.indexOf(color)}
            name={color}
            refresh={this.refreshState}
        />
    )
}, this); // pass the scope to .map

我试图在map方法中调用this.refreshState 当然,这与render方法的作用域不同。 解决方案是将范围存储在变量中:

var refresh = this.refreshState;

然后在map方法中使用该变量:

... refreshState={refresh} ...

始终注意您的范围!

如果您有多个功能不属于局部范围内,则可以存储this变量中。

var self = this;
z.map(function(arg) {
    x={self.refreshState} y={self.otherThing}

出于好奇,最终结果是:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <script src="http://fb.me/react-with-addons-0.12.2.js"></script>
    <script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
</head>
<body>
    <style>
        /* CSS */
        span {
            margin:0 0 0 10px;
        }
    </style>
    <div id="app"></div>
    <script type="text/jsx">
        // React

        var _data = ['Red', 'Blue', 'Green'];


        function getState() {
            return {
                colors: _data,
            }
        };


        Array.prototype.swap = function(a, b) {
            var temp = this[a];
            this[a] = this[b];
            this[b] = temp;
        };


        var App = React.createClass({

            getInitialState: function() {
                return getState();
            },

            refreshState: function() {
                return this.setState(getState());
            },

            render: function() {
                var self = this;
                var colors = this.state.colors.map(function(color) {
                    return (
                        <Color 
                            key={_data.indexOf(color)}
                            name={color}
                            refresh={self.refreshState}
                        />
                    )
                });
                return (
                    <ul>{colors}</ul>
                )
            },

        });


        var Color = React.createClass({

            propTypes: {
                name: React.PropTypes.string,
                refresh: React.PropTypes.func.isRequired,
            },

            moveUp: function() {
                var current = _data.indexOf(this.props.name),
                    above = current - 1;

                if (above >= 0) {
                    _data.swap(current, above);
                }

                return this.props.refresh();
            },

            moveDown: function() {
                var current = _data.indexOf(this.props.name),
                    below = current + 1;

                if (below < _data.length) {
                    _data.swap(current, below);
                }

                return this.props.refresh();
            },

            render: function() {
                return (
                    <li>
                        <strong>{this.props.name}</strong>
                        <span onClick={this.moveUp}>^</span> 
                        <span onClick={this.moveDown}>v</span>
                    </li>
                )
            },

        });


        React.render(<App />, document.getElementById('app'));
    </script>
</body>
</html>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM