2

I'm trying to emulate focus/ blur event in react native with no success. I have two components, Home and Button. In home i render a list of buttons(category1, category2 and category3). Here is my code:

---HOME COMPONENT----

state = {
    categories: ['category1', 'category2', 'category3']
};

renderCategories() {
    return this.state.categories.map((category, index) => (
        <Button onPress={() => this.getCategories(category)} key={index}>
            {category}
        </Button>
    ));
}

render() {
    return (
        <View>
            <ScrollView horizontal showsHorizontalScrollIndicator={false} style={{marginBottom: 5}}>
                {this.renderCategories()}
            </ScrollView>
        </View>

    )
}

---BUTTON COMPONENT---

class Button extends Component {
    constructor(props) {
        super(props);
        this.state = { pressStatus: false };
    }

    _onHideUnderlay() {
        this.setState({ pressStatus: false });
        console.log('unpressed')
    }
    _onShowUnderlay() {
        this.setState({ pressStatus: true });
        console.log('pressed')
    }

    render () {

        const {buttonStyle, buttonPressedStyle, textStyle} = styles;
        return (
            <TouchableHighlight onPress={this.props.onPress}
                                underlayColor={'#fff000'}
                                activeOpacity={1}
                                style={[buttonStyle, this.state.pressStatus ? {backgroundColor: '#fff000'} : {backgroundColor: '#1D36FF'}]}
                                // onHideUnderlay={this._onHideUnderlay.bind(this)}
                                onShowUnderlay={this._onShowUnderlay.bind(this)}>
                <Text style={textStyle}>
                    {this.props.children}
                </Text>
            </TouchableHighlight>
        );
    }


}

const styles = {
    buttonStyle: {
        marginTop:10,
        paddingTop:15,
        paddingBottom:25,
        marginLeft:10,
        // marginRight:10,
        paddingLeft: 15,
        paddingRight: 15,
        backgroundColor:'rgba(99,99,99,0.99)',
        borderRadius:10,
        borderWidth: 1,
        borderColor: '#fff'
    },
    buttonPressedStyle: {
        marginTop:10,
        paddingTop:15,
        paddingBottom:25,
        marginLeft:10,
        // marginRight:10,
        paddingLeft: 15,
        paddingRight: 15,
        backgroundColor:'rgba(15,15,15,0.99)',
        borderRadius:10,
        borderWidth: 1,
        borderColor: '#fff'
    },
    textStyle: {
        color:'#fff',
        textAlign:'center',
        fontSize: 16
    },
};

This code works partially. When i click first button(category1) it changes the background color as expected, but when i click second button(category2) then the button category1 should take the initial style(lost focus).

Please help. Thanks

4

1 回答 1

2

@Aramillo,您正面临这个问题,因为您pressStatus对所有三个按钮使用相同的属性值。

以某种不同的方式进行。

请尝试以下代码 -

App.js中

import React, { Component } from "react";
import { ScrollView, Text, View } from "react-native";
import Button from "./Button";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pressedButton: null,
      categories: ["category1", "category2", "category3"]
    };
  }

  getCategories = (category, index) => {
    this.setState({ pressedButton: index });
  };

  renderCategories() {
    return this.state.categories.map((category, index) => (
      <Button
        onPress={() => this.getCategories(category, index)}
        buttonId={index}
        pressedButton={this.state.pressedButton}
        key={index}
      >
        <Text>{category}</Text>
      </Button>
    ));
  }

  render() {
    return (
      <View>
        <ScrollView
          horizontal
          showsHorizontalScrollIndicator={false}
          style={{ marginBottom: 5 }}
        >
          {this.renderCategories()}
        </ScrollView>
      </View>
    );
  }
}

export default App;

Button.js 中

import React, { Component } from "react";
import { TouchableHighlight, Text } from "react-native";

class Button extends Component {
  constructor(props) {
    super(props);
    this.state = { pressStatus: false };
  }

  onHideUnderlay() {
    this.setState({ pressStatus: false });
    console.log("unpressed");
  }
  _onShowUnderlay() {
    this.setState({ pressStatus: true });
    console.log("pressed");
  }

  render() {
    const { buttonStyle, textStyle } = styles;
    return (
      <TouchableHighlight
        onPress={this.props.onPress}
        underlayColor={"#fff000"}
        activeOpacity={1}
        style={[
          buttonStyle,
          this.props.buttonId === this.props.pressedButton
            ? { backgroundColor: "#fff000" }
            : { backgroundColor: "#1D36FF" }
        ]}
        // onHideUnderlay={this._onHideUnderlay.bind(this)}
        onShowUnderlay={this._onShowUnderlay.bind(this)}
      >
        <Text style={textStyle}>{this.props.children}</Text>
      </TouchableHighlight>
    );
  }
}

export default Button;

const styles = {
  buttonStyle: {
    marginTop: 10,
    paddingTop: 15,
    paddingBottom: 25,
    marginLeft: 10,
    // marginRight:10,
    paddingLeft: 15,
    paddingRight: 15,
    backgroundColor: "rgba(99,99,99,0.99)",
    borderRadius: 10,
    borderWidth: 1,
    borderColor: "#fff"
  },
  buttonPressedStyle: {
    marginTop: 10,
    paddingTop: 15,
    paddingBottom: 25,
    marginLeft: 10,
    // marginRight:10,
    paddingLeft: 15,
    paddingRight: 15,
    backgroundColor: "rgba(15,15,15,0.99)",
    borderRadius: 10,
    borderWidth: 1,
    borderColor: "#fff"
  },
  textStyle: {
    color: "#fff",
    textAlign: "center",
    fontSize: 16
  }
};

这里的工作示例 - https://codesandbox.io/s/empty-currying-cikw4

于 2020-01-24T16:55:57.447 回答