我有一个元素列表。当我点击向上或向下图标时,我希望列表重新排列自己,最后,让应用程序重新渲染自己,这样我就可以看到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>
答案 0 :(得分:1)
注意到你已经解决了这个问题,但我想提到你可以将范围传递给.map,这意味着不需要为你描述的目的缓存范围:
this.state.colors.map(function(color) {
return (
<Color
key={_data.indexOf(color)}
name={color}
refresh={this.refreshState}
/>
)
}, this); // pass the scope to .map
答案 1 :(得分:0)
我试图在this.refreshState
方法中调用map
。当然,这与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>