Danny Dyer Danny Dyer - 1 month ago 8
React JSX Question

React with Redux - unable to bind action to parent

I am new to the Redux pattern i'm having some trouble linking an action in a separate JS file to it's parent component. Here is the component:

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import playSample from './sampleActions/clickToPlay';

class SamplesInnerLrg extends Component {
render() {
return <div>
{
this.props.samples.map((sample) => {
return (
<div key={sample.id} className="sample-comp-lge">
<div className="sample-comp-lge-header">
<span className="sample-comp-lge-Name">{sample.sampleName}</span>
<span className="sample-comp-lge-id">{sample.sampleFamily}</span>
</div>
<div className="sample-comp-lge-audio" ref={sample.id} onClick={() => this.bind.playSample(sample)}>
<audio preload="auto" id="myAudio">
<source src={sample.soundSource} type="audio/wav" />
</audio>
</div>
<div className="sample-comp-lge-owner">{sample.uploader}</div>
</div>
)
})
}
</div>
}
}

function mapStateToProps(state) {
return {
samples:state.samples
};
}

function matchDispatchToProps(dispatch) {
return bindActionCreators({playSample:playSample},dispatch)
}

export default connect(mapStateToProps,matchDispatchToProps)(SamplesInnerLrg);


Specifically I am trying to have an onClick action on this line that will call a function in an imported file (clickToPlay.js):

<div className="sample-comp-lge-audio" ref={sample.id} onClick={() => this.bind.playSample(sample)}>


The clickToPlay file looks like so:

import $ from 'jquery';

export const playSample = (sample) => {
console.log(sample);

return {
type:"Play_Sample_clicked",
payload:sample
}
};


the error i'm getting on click is Cannot read property 'playSample' of undefined. I'm guessing I have bound the action to the component correcly but I can't tell why?

EDIT:

Here is my index.js file as requested:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {Provider} from 'react-redux';
import { createStore,compose } from 'redux';
import allReducers from './reducers';

const store = createStore(allReducers,compose(
window.devToolsExtension ? window.devToolsExtension() : f => f
));

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
,
document.getElementById('root')
);

Answer

You aren't exporting 'playSample' as the default export, you have two ways to reslove this:

You can do:

import { playSample } from './sampleActions/clickToPlay';

or

you can change export const playSample to const playSample Then add export default playSample at the end of your file.

Another note I want to mention about this line:

return bindActionCreators({playSample:playSample},dispatch)

I don't see why you are doing {playSample:playSample} just change it to playSample. ES6 allows you to eliminate key if it's the same as value, this is called object literal property value shorthand.

Comments