好吧,我意识到这段代码很臭,但请耐心等待我一会儿。
我在这里玩代码,我有一个奇怪的情况,this
关键字。
在下面的代码片段中,我希望按下按钮TopBar
以触发index.ios.js
中的goose
方法,它确实如此。 然而,里面goose
this
指的是曾孙:
儿童 =ComponentOne
孙子 =VoterScreen
曾孙=TopBar
显然,这是由于我将props
传递给TopBar
的方式,我确信这不是"React Native 方式",但任何人都可以告诉我:
1 - 如何调整下面的代码并正确引用this
(从我读到的内容来看,由于状态更改,render
再次调用,无需调用 forceUpdate())。
或:
2 - 如何通过编辑callbacks
的工作方式,使曾孙拨打goose
,其中this
是我期望的this
。
index.ios.js
的代码:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
View
} from 'react-native';
import VoterScreen from './components/voter-screen.js'
export default class StyleAB extends Component {
constructor(props)
{
super(props);
this.state =
{
componentSelected: 'One',
}
}
changeComponent = (component) =>{
this.setState({componentSelected: component});
}
goose(){
console.log('State before: ' + JSON.stringify(this.state));
this.state = { componentSelected: 'Two', }
console.log('State after: ' + JSON.stringify(this.state));
this.forceUpdate();
}
renderComponent(component) {
if(component == 'One') {
return <ComponentOne changeComponent={this.changeComponent} goose={this.goose} />
} else if(component == 'Two') {
return <ComponentTwo changeComponent={this.changeComponent} />
} else if(component == 'Three') {
return <ComponentThree changeComponent={this.changeComponent} />
}
}
render() {
console.log('Render is called');
return (
<View style={styles.container}>
{this.renderComponent(this.state.componentSelected)}
</View>
);
}
}
class ComponentOne extends Component {
render() {
return (
<VoterScreen sendData={this.props.goose}/>
)
}
}
class ComponentTwo extends Component {
render() {
return (
<UploadScreen/>
)
}
}
class ComponentThree extends Component {
render() {
return (
<ResultsScreen/>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
}
});
AppRegistry.registerComponent('StyleAB', () => StyleAB);
voter-screen.js
的代码:
import React, { Component } from 'react';
import { View } from 'react-native';
import { Button } from 'react-native-elements';
import TopBar from './top-bar.js'
class VoterScreen extends Component {
render() {
console.log('Render is called in VoterScreen');
let topIsA = true;
return (
<View style={{flex: 1}}>
<TopBar parentToggle={this.props.sendData}/>
</View>
);
}
}
export default VoterScreen
top-bar.js
的代码:
import React, { Component } from 'react'
import { View } from 'react-native';
import { Button } from 'react-native-elements';
class TopBar extends Component {
render() {
console.log('Render is called in TopBar');
return (
<View style={{flex: 1, flexDirection: 'row', backgroundColor: 'black'}}>
<Button
raised
containerViewStyle={{backgroundColor: 'black'}}
icon={{name: 'camera', type: 'font-awesome', size: 20, style: {marginRight: 0, textAlign: 'center'}}}
buttonStyle={{backgroundColor: '#cd00cd', borderRadius: 10, width: 50, height: 50}}
onPress={this.props.parentToggle.bind(this)}
/>
</View>
)
}
}
export default TopBar
编辑: 答案是做三件事:
1 -index.ios.js
:
改变:
return <ComponentOne changeComponent={this.changeComponent} goose={this.goose} />
自:
return <ComponentOne changeComponent={this.changeComponent} goose={this.goose.bind(this)} />
2 - 在同一文件中:
改变:
<VoterScreen sendData={this.props.goose}/>
自:
<VoterScreen sendData={this.props.goose.bind(this)}/>
[谢谢克里斯]。
3 -top-bar.js
:
改变:
onPress={this.props.parentToggle.bind(this)}
自:
onPress={this.props.parentToggle}
[谢谢爱德华]。
尝试在像这样传递之前绑定范围...
<VoterScreen sendData={this.props.goose.bind(this)}/>
如果你想让this
引用父组件,为什么要在曾孙中绑定它? 你试过这条路吗?
onPress={this.props.parentToggle}
或者这个:
onPress={() => this.props.parentToggle}
不确定我是否正确阅读了您的问题,但将goose(){
更改为goose = () => {
应该可以解决您的所有问题。此外,在渲染中绑定对性能不利,因此您可能希望在要在构造函数中绑定或绑定的每个组件上创建另一个方法。