如何更改子组件按钮的图像并从父组件导航



我有一个名为<TopBar>的组件,它将包含在其他组件中。 目标是当我单击<TopBar/>上的任何项目(重定向到其他页面(时,它应该更新state并导航到新页面。

孩子:

var width = Dimensions.get('window').width;
// const { navigate } = this.props.navigation;

class TopBar extends Component {
constructor(props) {
super(props)
this.state = {
profile: require('../../img/profile.png'),
mail: require('../../img/mail_icon.png'),
setting: require('../../img/settings.png'),
notification: require('../../img/notification.png'),
logout: require('../../img/logout.png'),
home: require('../../img/home.png')
}
}

onchangeLinkName = (no) => {
if (no === 1)
this.setState({
home: require('../../img/home.png')
});
else if (no === 2)
this.setState({
mail: require('../../img/mail_icon_2.png')
});
else if (no === 3)
this.setState({
notification: require('../../img/notification_2.png')
});
else if (no === 4)
this.setState({
profile: require('../../img/profile_2.png')
});
else if (no === 5)
this.setState({
logout: require('../../img/logout.png')
});
}
home_pressin = () => {
this.setState({
home: require('../../img/home.png')
});
}
home_pressout = () => {
this.setState({
home: require('../../img/home_2.png')
});
}
logout_pressin = () => {
this.setState({
logout: require('../../img/logout.png')
});
}
logout_pressout = () => {
this.setState({
logout: require('../../img/logout_2.png')
});
}
notification_pressin = () => {
this.setState({
notification: require('../../img/notification_2.png')
});
}
notification_pressout = () => {
this.setState({
notification: require('../../img/notification.png')
});
}
setting_pressin = () => {
this.setState({
setting: require('../../img/settings_2.png')
});
}
setting_pressout = () => {
this.setState({
setting: require('../../img/settings.png')
});
}
profile_pressin = () => {
this.setState({
profile: require('../../img/profile_2.png')
});
}
profile_pressout = () => {
this.setState({
profile: require('../../img/profile.png')
});
}
mail_pressin = () => {
this.setState({
mail: require('../../img/mail_icon_2.png')
});
}
mail_pressout = () => {
this.setState({
mail: require('../../img/mail_icon.png')
});
}
tonotification = () => {
//  navigate('page3')
this.props.navigation.navigate('notification');
}
tomail = () => {
//  navigate('page3')
this.props.navigation.navigate('mail');
}
toprofile = () => {
//  navigate('page3')
this.props.navigation.navigate('profile');
}
tohome = () => {
//  navigate('page3')
this.props.navigation.navigate('Home',{});
// this.setState({
//     // home: require('../../img/mail_icon.png')
// });
}
tosignin = () => {
//  navigate('page3')
this.props.navigation.navigate('Login');
}
_changeStyle() {
//var color = colors[Math.floor(Math.random()*colors.length)];
//var backgroundColor = backgroundcolors[Math.floor(Math.random()*backgroundcolors.length)];
this.setState({
})
}
render() {

return (
<View>
<ImageBackground source={require('../../img/blue_bar_for_every_screen.png')}
style={styles.foregroundImage} >
<View style={{ marginTop: 15, padding: 10, flexDirection: 'row', justifyContent: 'space-evenly' }}>
<View style={{}}>
<TouchableWithoutFeedback onPress={this.tohome} onPressIn={this.home_pressin} onPressOut={this.home_pressout}>
<Image
style={styles.button_header}
source={this.state.home}
/>
</TouchableWithoutFeedback>
</View>
<View style={{}}>
<TouchableWithoutFeedback onPress={this.tomail} onPressIn={this.mail_pressin} onPressOut={this.mail_pressout}>
<Image
style={styles.button_header}
source={this.state.mail}
/>
</TouchableWithoutFeedback>
</View>
{/* <View style={{}}>
<TouchableWithoutFeedback onPressIn={this.setting_pressin} onPressOut={this.setting_pressout}>
<Image
style={styles.button_header}
source={this.state.setting}
/>
</TouchableWithoutFeedback>
</View> */}
<View style={{}}>
<TouchableWithoutFeedback onPress={this.tonotification} onPressIn={this.notification_pressin} onPressOut={this.notification_pressout}>
<Image
style={styles.button_header}
source={this.state.notification}
/>
</TouchableWithoutFeedback>
</View>
<View style={{}}>
<TouchableWithoutFeedback onPress={this.toprofile} onPressIn={this.profile_pressin} onPressOut={this.profile_pressout}>
<Image
style={styles.button_header}
source={this.state.profile}
/>
</TouchableWithoutFeedback>
</View>
<View style={{}}>
<TouchableWithoutFeedback onPress={this.tosignin} onPressIn={this.logout_pressin} onPressOut={this.logout_pressout}>
<Image
style={styles.button_header}
source={this.state.logout}
/>
</TouchableWithoutFeedback>
</View>
</View>
</ImageBackground>
</View>
)
}
}

父母:

export default class Notification extends Component {

_changeStyle() {
//var color = colors[Math.floor(Math.random()*colors.length)];
//var backgroundColor = backgroundcolors[Math.floor(Math.random()*backgroundcolors.length)];
this.setState({
})
}
render() {
const username = "";
const password = "";

return (
<ImageBackground source={require('../../img/img_login_back.png')} style={styles.backgroundImage}>
<View style={{}}>
<TopBar>
{/* {this.props.Notification.spilit(' ').map((word))} */}
{/* <DefaultRenderer
navigationState={this.props.children[0]}
onNavigate={this.props.onNavigate}
/> */}
{/* {React.createElement(this.props.children[0].component, {key: "you can pass props here"})} */}
</TopBar>
<View style={{justifyContent:'center',marginTop:100}}>
<Text style={{ position: 'absolute', fontSize: 20, fontWeight: 'bold', fontFamily: 'Verdana' }}>
No Design Provided For Notification
</Text>
</View>
</View>
</ImageBackground>
)
}
}

如果我正确遵循,听起来您想做一些类似于我在以下代码片段中演示的事情。

在此示例中,状态在父级中进行管理,父级维护当前的"项",即要导航到的页面。 这以子属性currentItem的形式传递给子组件。

同时,我传递了父项的changeItem方法,该方法允许子项在父项的状态下更改此值。

最后,子项中有逻辑可以查看其各自的项是否与父项当前选择的项目匹配,以便子项可以根据所选内容具有不同的行为。 请注意,此示例中不需要子状态。 所有必要的数据都是通过传递到子级的属性来捕获的。

这可能不完全是您要做的,但我认为它可能足以解释如何在父组件和子组件之间同步状态/道具......?

class Parent extends React.Component {
constructor() {
super();
this.state = { item: 1 };
}
changeItem = newItem => {
this.setState({ item: newItem });
};
render() {
const { item } = this.state;
return (
<div>
<h2>
Parent -{" "}
<code>
Item=[
{item}]
</code>
</h2>
<h4>Separate Children</h4>
<SeparateChild currentItem={item} childItem={1} changeItem={this.changeItem} />
<SeparateChild currentItem={item} childItem={2} changeItem={this.changeItem} />
<SeparateChild currentItem={item} childItem={3} changeItem={this.changeItem} />
<h4>One Child</h4>
<OneChild currentItem={item} changeItem={this.changeItem} />
</div>
);
}
}
class SeparateChild extends React.Component {
constructor(props) {
super(props);
}
render() {
const { childItem, currentItem, changeItem } = this.props;
return (
<input
type="button"
style={{ marginRight: "5px", textAlign: "left", width: "200px" }}
onClick={() => changeItem(childItem)}
value={`Child - change to [${childItem}]${childItem === currentItem ? " [ACTIVE]" : ""}`}
/>
);
}
}
class OneChild extends React.Component {
constructor(props) {
super(props);
}
render() {
const { currentItem, changeItem } = this.props;
const childItems = [1, 2, 3];
return (
<div>
{childItems.map(childItem => {
return (
<input
type="button"
style={{ marginRight: "5px", textAlign: "left", width: "200px" }}
onClick={() => changeItem(childItem)}
value={`Child - change to [${childItem}]${childItem === currentItem ? " [ACTIVE]" : ""}`}
/>
);
})}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Parent />, rootElement);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

发布编辑:我修改了代码段,以演示如何通过原始的单独组件或在单个组件中处理的相同行为来管理子属性。

最新更新