我在学习如何在React Native中在父子之间传递数据时遇到了麻烦。
在我的父组件中,我有一个state属性(audioPlaying),它是一个布尔值。
state = {
//The title informs the Button and TitleArea components
title: 'hello',
audioPlaying: false,
};
我想通过按一个按钮(onPress)来更改该值。
<Button
title={this.state.title}
onPress={this.playPauseHandler}
audioPlaying={this.state.audioPlaying}
/>
...通过调用playPauseHandler。
playPauseHandler = () => {
this.setState(prevState => ({
audioPlaying: !prevState.audioPlaying
}));
}
然后在我的孩子(按钮)组件中,我想评估audioPlaying状态属性。如果是真的,我想展示一件事,而假的我想展示另一件事。
<View style={styles.playBtnStyle}>
{this.props.audioPlaying === false ? (
<MaterialIcons
name='play-arrow'
size={50}
color="#87888C"
/>
) : (
<MaterialIcons
name='pause'
size={50}
color="#87888C"
/>
)}
}
</View>
但是,当我运行它时,我无法获得audioPlaying的值。 React Native Error Message
这是这两个文件的完整文件:
App.js
import React, { Component } from 'react';
import { View, StatusBar } from 'react-native';
import Carousel from './src/components/Carousel/Carousel';
import Button from './src/components/Button/Button';
import TitleArea from './src/components/TitleArea/TitleArea';
import MapArea from './src/components/MapArea/MapArea';
const styles = {
container: {
flex: 1,
justifyContent: 'space-between',
},
playArea: {
flex: 1,
},
};
export default class App extends Component {
state = {
//The title informs the Button and TitleArea components
title: 'hello',
audioPlaying: false,
};
playPauseHandler = () => {
this.setState(prevState => ({
audioPlaying: !prevState.audioPlaying
}));
}
render() {
return (
<View style={styles.container}>
<TitleArea title={this.state.title} />
<StatusBar hidden={false} />
<Carousel />
<MapArea />
<Button
title={this.state.title}
onPress={this.playPauseHandler}
audioPlaying={this.state.audioPlaying}
/>
</View>
);
}
}
Button.js
import React, { Component } from 'react';
import { Text, View, TouchableOpacity, Dimensions } from 'react-native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
const { width } = Dimensions.get('window');
const height = width * 0.2;
const styles = {
textStyle: {
color: '#87888C',
fontSize: 18,
fontWeight: '600',
backgroundColor: 'white',
alignSelf: 'center',
},
buttonContainer: {
height,
flexDirection: 'row',
backgroundColor: 'white',
alignItems: 'center',
},
playBtnStyle: {
marginLeft: 50,
backgroundColor: 'white',
},
childStyle: {
flex: 1,
},
};
const button = (props) => {
return (
<View style={styles.buttonContainer}>
<TouchableOpacity>
<View style={styles.playBtnStyle}>
{this.props.audioPlaying === false ? (
<MaterialIcons
name='play-arrow'
size={50}
color="#87888C"
/>
) : (
<MaterialIcons
name='pause'
size={50}
color="#87888C"
/>
)}
}
</View>
</TouchableOpacity>
<View style={styles.childStyle}>
<Text style={styles.textStyle}>Chapter 1: {props.title}</Text>
</View>
</View>
);
}
export default button;
答案 0 :(得分:4)
按钮上下文中没有this
。那只是一个返回JSX的函数。
而是使用props
<View style={styles.playBtnStyle}>
{props.audioPlaying === false ? (
<MaterialIcons
name='play-arrow'
size={50}
color="#87888C"
/>
) : (
<MaterialIcons
name='pause'
size={50}
color="#87888C"
/>
)}
</View>
答案 1 :(得分:0)
好,所以我解决了我自己的问题! (成为开发人员的第一步)
两个问题:
捕获触摸事件
React Native具有所谓的Touchables。根据文档,这些是“使视图正确响应触摸的包装器”。
TouchableOpacity,我正在使用的那个
按下时,已包装视图的不透明度降低,从而使其变暗。不透明度是通过将子级包装在Animated.View中控制的,该视图已添加到视图层次结构中。
https://facebook.github.io/react-native/docs/touchablewithoutfeedback#onpress
所有可触摸对象均接受onPress道具。因此,通过将onPress道具添加到Touchable中,我可以捕获触摸事件,而不仅仅是触发它。
将回调传递给家长
本文帮助我更多地了解了如何从孩子那里调用父函数。
https://medium.com/@thejasonfile/callback-functions-in-react-e822ebede766
因此,我在TouchableOpacity中调用playPause()(我重命名了prop并对其进行了结构分解),该事件从触摸事件触发,导致状态改变和组件重新呈现。
const button = (props) => {
const {
title,
audioPlaying,
playPause,
} = props;
return (
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={() => playPause()}>
<View style={styles.playBtnStyle}>
{audioPlaying === false ? (
<MaterialIcons
name='play-arrow'
size={50}
color="#87888C"
/>
) : (
<MaterialIcons
name='pause'
size={50}
color="#87888C"
/>
)
}
</View>
</TouchableOpacity>
<View style={styles.childStyle}>
<Text style={styles.textStyle}>
Chapter 1:
{title}
</Text>
</View>
</View>
);
};