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

时间:2018-10-18 17:03:19

标签: reactjs react-native react-native-android

我有一个名为<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>
        )
    }

}

1 个答案:

答案 0 :(得分:0)

如果我正确遵循的话,听起来您想做的事情就像我在以下片段中演示的那样。

在此示例中,状态在父级中管理,父级维护当前的“项目”,即您要导航至的页面。它以子属性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>

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