如何从React/Redux的@connect装饰器调用组件方法
@connect-Wrapped Components for Click Events in Render Objects Hey there! Let's break this down step by step—this is a super common gotcha when you're new to React and Redux, so you're definitely not alone here. The core issue isn't actually the @connect decorator itself, but making sure your component's internal methods are properly bound so this points to your component instance when the click fires.
Here are the most reliable ways to solve this:
1. Use Class Fields with Arrow Functions (Cleanest Approach)
Arrow functions in class fields automatically bind this to your component instance, so you don't have to worry about manual binding. This is my go-to for modern React code:
import { connect } from 'react-redux'; class YourComponent extends React.Component { // Define your handler as an arrow function to auto-bind `this` handleOptionClick = (optionId) => { console.log(`Clicked option: ${optionId}`); // You can access this.props (from Redux) or this.state here safely this.props.someReduxAction(optionId); }; // Your render object, now referencing the bound handler optionsRender = { userSettings: ( <div key="user-settings" onClick={() => this.handleOptionClick('user-settings')}> User Settings </div> ), helpCenter: ( <div key="help-center" onClick={() => this.handleOptionClick('help-center')}> Help Center </div> ) }; render() { return ( <div className="options-container"> {Object.values(this.optionsRender)} </div> ); } } // Your Redux mapping functions (adjust as needed) const mapStateToProps = (state) => ({ // Your mapped state here }); const mapDispatchToProps = { // Your mapped actions here }; export default connect(mapStateToProps, mapDispatchToProps)(YourComponent);
2. Bind Methods in the Constructor
If you prefer not to use class fields, you can explicitly bind your handler to the component instance in the constructor:
import { connect } from 'react-redux'; class YourComponent extends React.Component { constructor(props) { super(props); // Bind the handler to `this` so it references the component instance this.handleOptionClick = this.handleOptionClick.bind(this); } handleOptionClick(optionId) { console.log(`Clicked option: ${optionId}`); this.props.someReduxAction(optionId); } optionsRender = { userSettings: ( <div key="user-settings" onClick={() => this.handleOptionClick('user-settings')}> User Settings </div> ) }; render() { return <div>{Object.values(this.optionsRender)}</div>; } } // Redux mappings same as above export default connect(mapStateToProps, mapDispatchToProps)(YourComponent);
3. Avoid This: Inline Binding in the Render Object
You could technically bind directly in the onClick prop, but this creates a new function every time the component renders, which can hurt performance if the component re-renders frequently. It's better to use the two methods above:
// Not recommended, but works if you're in a pinch optionsRender = { userSettings: ( <div key="user-settings" onClick={this.handleOptionClick.bind(this, 'user-settings')}> User Settings </div> ) };
Quick Note on @connect
Remember: The @connect decorator only maps Redux state and dispatch actions to your component's props—it doesn't change how this works inside your component. The key is ensuring your methods are bound so this points to the component instance, not the optionsRender object or something else.
内容的提问来源于stack exchange,提问作者MarcioPorto

