我仍然在开始反应,现在我已经使用我的第二个解决方案(这里)来显示/隐藏组件。
我现在的问题是,如果我有多个子元素并且我需要打开另一个组件(首选项)(我已经管理过了,单击外部或其他地方会隐藏它),但同时我需要将信息传递给另一个组件。我已经附上了我的小演示。我的问题再次是我如何从Child
/Child2
组件传递到Preferences
组件,说它是_preferences
或坐标?
编辑:添加了JSFIDDLE链接。
整个代码片段:
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.7.0/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div id="render-here"></div>
<script type="text/jsx">
var Parent = React.createClass({
getInitialState: function () {
return {
showPreference: false,
childComponents: 0
};
},
shouldComponentUpdate: function() {
console.log('parent should update');
return true;
},
_click: function() {
this.setState({childComponents: this.state.childComponents + 1});
},
_showPreference: function() {
this.setState({showPreference: true})
},
_hidePreference: function() {
this.setState({showPreference: false})
},
render: function() {
var childComponents = [];
_.times(this.state.childComponents, function(n) {
if (n % 2)
childComponents.push(<Child key={'foobar'+n} showPreference={this._showPreference} />)
else
childComponents.push(<Child2 key={'foobar'+n} showPreference={this._showPreference} />)
}.bind(this));
return(
<div style={{height:'100%', width:'100%', border:'1px solid blue'}} onClick={this._hidePreference}>
{this.state.showPreference ? <Preference /> : null}
<div onClick={this._click}>Add components</div>
{childComponents}
</div>
)
}
});
var Preference = React.createClass({
shouldComponentUpdate: function() {
console.log('preference should update');
return true;
},
_click: function(e) {
e.stopPropagation();
},
render: function() {
return(
<div ref="pref" style={{position:'absolute', left: '250px'}} onClick={this._click}>
<div>Some preferences here...</div>
</div>
)
}
});
var Child = React.createClass({
shouldComponentUpdate: function() {
console.log('child should update');
return true;
},
_preferences: ['child', 'preferences'],
_click: function(e) {
e.stopPropagation();
this.props.showPreference();
},
render: function() {
return(
<div ref="me" onClick={this._click}>Child - click me for preference</div>
)
}
});
var Child2 = React.createClass({
shouldComponentUpdate: function() {
console.log('child should update');
return true;
},
_preferences: ['child2', 'preferences'],
_click: function(e) {
e.stopPropagation();
this.props.showPreference();
},
render: function() {
return(
<div ref="me" onClick={this._click}>Child 2 - click me for preference</div>
)
}
});
React.render(<Parent name="foobar" />, document.getElementById('render-here'));
</script>
</body>
</html>
JSFIDDLE 链接。
首先,永远不要在 React 组件中存储任意对象,就像使用 _preferences: ['child', 'preferences']
一样。组件中的任何数据都应位于该组件的state
内,或者作为props
传递给该组件。
如果在组件对象上放置这样的数组,它将在该组件的所有实例之间共享。如果你只有一个实例,你可能不会注意到它。但一旦你需要更多,它可能会咬你。通过使用 state
和 setState
来改变它,React 知道何时重新渲染你的组件。
现在回答你的问题;你的Parent
组件可能应该是将preferences
对象保持在它状态的组件。然后Parent
组件将其传递给Child
、Child2
和Preference
组件作为道具。如果Child
、Child2
或Preference
想要修改该对象,Parent
会传递一个回调作为道具给他们,他们可以调用回调告诉Parent
应该更改它。像这样:
let React = require('react');
let Parent = React.createClass({
getInitialState() {
return {
preferences: {
someKey: 'someValue'
}
};
},
changePreference(pref) {
this.setState(state => {
state.preferences[pref.name] = pref.value;
return state;
});
},
render() {
return (
<div>
<Child
preferences={this.state.preferences}
onChangePreference={pref => this.changePreference(pref)}
/>
<Preference
preferences={this.state.preferences}
onChangePreference={pref => this.changePreference(pref)}
/>
</div>
);
}
});