Nicholas Nicholas - 3 months ago 21
Javascript Question

How to pass class instances to react children without breaking updates?

In a react-redux app what is the best practice for passing collections of action creators to child components?

To be more specific I want to have a class that performs network requests for me. I want to make different instances of that class for different endpoints. The methods in that class are action creators. How do I pass a specific instance of that class to my subcomponents without breaking redux connect shallow comparison? Do I have to implement custom shouldComponentUpdate methods? Is there a whole better way of doing this?

Answer

usually components divided for better maintainability : HOC(container) and presentatianal components..

if your container includes presentational components:

You don't need to pass your actions creators through presentations components, because they shouldn't have any knowledge of redux parts. If presentational component fires some action , you should use callbacks to invoke dispatch in container.

for using different instances of action creator class

first way

import ActionsClass from './Actions/ActionsClass';
const actions = ActionsClass('endpoint');

class Container extends Component {...}
export default connect(state=>({foo:state.foo}),actions)(Container);

second dynamic way, passing endpoint through props

import ActionsClass from './Actions/ActionsClass';
import { bindActionCreators } from 'redux'

class Container extends Component {...}

const mapDispatchToProps = (dispatch,ownProps)=>({
   actions: bindActionCreators(ActionsClass(ownProps.endpoint) , dispatch) 
});

export default connect(state=>({foo:state.foo}),mapDispatchToProps)(Container);

i guess, you may use reselect for ActionsClass(ownProps.endpoint)

third dynamic way without Class, passing endpoint to action

import actions from './actions';

class Container extends Component {
    onChange(arg1,arg2){
       this.props.someAction(arg1,arg2,this.props.endpoint)
    }
    render(){
       return(<SomeComp onChange={this.onChange.bind(this)}/>
    }
}

export default connect(state=>({foo:state.foo}),actions)(Container);

btw, also you can pass endpoint from store state=>({endpoint:state.endpoint})

fourth... get endpoint from action creators, through redux-thunk

const actionFetch = (notes) => (dispatch,getState)=>{
    let endpoint = getState()[notes].endpoint;
    fetch(endpoint).then(...
    //or let endpoint = endpointsFromModule[notes].fetchAll;
}
Comments