You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Touchable组件按压样式切换,多组件仅一个可选中(非Redux)

Solution: Centralize Active State in Parent Component

Got it, let's solve this problem without Redux—we can handle the active state centrally in the parent App component since it's the one rendering all ActivityButton instances. This approach keeps things simple, avoids redundant local state in child components, and ensures only one button is active at a time.

Step 1: Update the App Component

First, we'll add a state variable to track the currently active button, plus a handler to update this state when a button is pressed. We'll also pass each button its active status and press handler via props.

class App extends React.Component {
  constructor(props) {
    super(props);
    // Track the ID/title of the currently active button (null = no active button)
    this.state = {
      activeButtonId: null
    };
  }

  // Handler to update active state AND run your original submit logic
  handleButtonPress = (buttonId) => {
    // Set the pressed button as the active one
    this.setState({ activeButtonId: buttonId });
    // Execute your existing submit logic for the button
    this.submitHandler(buttonId);
  };

  submitHandler = (buttonId) => {
    // Your existing business logic here (e.g., API calls, form submissions)
    console.log(`Processing action for button: ${buttonId}`);
  };

  render() {
    return (
      <View>
        <ActivityButton
          activityTitle={"B1"}
          // Pass whether this button is currently active
          isActive={this.state.activeButtonId === "B1"}
          // Pass the centralized press handler
          onPress={() => this.handleButtonPress("B1")}
        />
        <ActivityButton
          activityTitle={"B2"}
          isActive={this.state.activeButtonId === "B2"}
          onPress={() => this.handleButtonPress("B2")}
        />
      </View>
    );
  }
}

Step 2: Simplify the ActivityButton Component

Now the child component no longer needs to manage its own active state—it just uses the isActive prop from the parent to determine its style. This makes the component fully reusable across your app without any state tied to activation.

class ActivityButton extends React.Component {
  render() {
    const { activityTitle, isActive, onPress } = this.props;
    return (
      <TouchableOpacity
        style={isActive ? styles.buttonPress : styles.button}
        onPress={onPress}
      >
        <View>
          <Text>{activityTitle}</Text>
        </View>
      </TouchableOpacity>
    );
  }
}

// Example styles (tweak these to match your app's design)
const styles = StyleSheet.create({
  button: {
    padding: 12,
    backgroundColor: '#f0f0f0',
    borderRadius: 6,
    marginVertical: 8,
    alignItems: 'center'
  },
  buttonPress: {
    padding: 12,
    backgroundColor: '#2196f3',
    borderRadius: 6,
    marginVertical: 8,
    alignItems: 'center',
    // Add subtle press feedback (e.g., slight scale down)
    transform: [{ scale: 0.97 }]
  }
});

Key Benefits of This Approach

  • Single Source of Truth: All button activation state lives in the parent, guaranteeing only one button is active at any time.
  • Fully Reusable: The ActivityButton component can be dropped anywhere in your app—just pass isActive and onPress props, no local state setup needed.
  • No Redux Required: We're using React's native parent-child prop flow, which is perfect for this localized state scenario.

Optional: Add Toggle Behavior

If you want clicking an already active button to deactivate it, adjust the handleButtonPress function like this:

handleButtonPress = (buttonId) => {
  this.setState(prevState => ({
    activeButtonId: prevState.activeButtonId === buttonId ? null : buttonId
  }));
  this.submitHandler(buttonId);
};

Optional: Use Unique IDs (Instead of Titles)

If your button titles might not be unique, add a uniqueId prop for safer state tracking:

// In App component's render
<ActivityButton
  uniqueId="btn-task-1"
  activityTitle={"B1"}
  isActive={this.state.activeButtonId === "btn-task-1"}
  onPress={() => this.handleButtonPress("btn-task-1")}
/>

内容的提问来源于stack exchange,提问作者RVieira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:07:55