Reputation: 1324
I started coding a web interface to manage my server's files using React/Redux.
I now have a page which requests my API to get files list as JSON.
It works well, I got my page with a list of all my files from server. But the select file action fails with the following error:
TypeError : _this2.props.selectFile is not a function
Here's my code :
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore, applyMiddleware, combineReducers} from 'redux';
import {Provider, connect} from 'react-redux';
import thunk from 'redux-thunk';
import activeFileReducer from './reducers/reducer-active-file';
import dataListReducer from './reducers/reducer-data';
const reducer = combineReducers({
datalist: dataListReducer,
activefile: activeFileReducer
})
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore)
let store = createStoreWithMiddleware(reducer);
ReactDOM.render(<Provider store={store}>
<App />
</Provider>, document.getElementById('table'));
datalist-reducer
export default function datalist (state = [], action) {
switch (action.type) {
case "FETCH_REQUEST":
return state;
case "FETCH_SUCCESS":
return action.payload || [];
default:
return state;
}
}
active-file-reducer
export default function activefile (state= {}, action){
switch(action.type){
case "FILE_SELECTED":
return action.payload;
default:
return state;
}
}
actions/index.js
export const selectFile = (file) => {
return {
type: "FILE_SELECTED",
payload: file
}
}
export const fetchDataRequest = () =>{
return {
type: "FETCH_REQUEST"
}
}
export const fetchDataSuccess = (payload) => {
return {
type: "FETCH_SUCCESS",
payload
}
}
export const fetchDataError = () => {
return {
type: "FETCH_ERROR"
}
}
data-list-container
import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {fetchDataRequest, fetchDataSuccess, fetchDataError, selectFile} from '../actions/index';
class DataList extends Component{
componentDidMount(){
this.props.fetchDataWithRedux()
}
render(){
return(
<ul>
{
this.props.datalist &&
this.props.datalist.map((item, key) =>{
return(
<li key={key} onClick={() => this.props.selectFile(item)}>{item.title}</li>
)
})
}
</ul>
)
}
}
function fetchDataWithRedux() {
return (dispatch) => {
dispatch(fetchDataRequest());
return fetchData().then(([response, json]) =>{
console.log(response);
if(response.status === 200){
dispatch(fetchDataSuccess(json))
dispatch(selectFile())
}
else{
dispatch(fetchDataError())
dispatch(selectFile())
}
})
}
}
function fetchData() {
const URL = "http://localhost:5000/api/deposit/view";
return fetch(URL, { method: 'GET'})
.then( response => Promise.all([response, response.json()]));
}
function mapStateToProps(state){
return {
datalist: state.datalist
}
}
export default connect(mapStateToProps, {fetchDataWithRedux})(DataList);
Upvotes: 2
Views: 1771
Reputation: 104379
Because you are not passing selectFile
function to component in props, here:
export default connect(mapStateToProps, {fetchDataWithRedux})(DataList);
Pass selectFile
in the same way as you are passing fetchDataWithRedux
, Use this:
export default connect(mapStateToProps, {fetchDataWithRedux, selectFile})(DataList);
Upvotes: 1
Reputation: 851
You can directly use selectFile instead of binding it to props when you have imported those to your component.
<li key={key} onClick={() => selectFile(item)}>{item.title}</li>
Just remove this.props. prefixed to selectFile
Upvotes: 0