简体   繁体   中英

React/Redux dispatch function doesn't work

I am using 'react-fileupload' to upload files on my server. In case of success I receive response with content of this file. So in one component I want to upload file and change stores state and in another component I want to show that data.

But i don't know why my dispatch function doesn't work.

Component with uploader:

import React, { Component } from 'react';
import FileUpload from 'react-fileupload';
import { connect } from 'react-redux';
import { updateOverview } from '../actions/index';
import { bindActionCreators } from 'redux';

class Header extends Component {
  render() {
    const options = {
      baseUrl: 'http://127.0.0.1:8000/api/upload_file',
      chooseAndUpload: true,
      uploadSuccess: function(res) {
        console.log('success');
        updateOverview(res.data);
      },
      uploadError: function(err) {
        alert(err.message);
      }
    };
    return (
      <div>
        <FileUpload options={options} ref="fileUpload">
          <button
            className="yellow darken-2 white-text btn-flat"
            ref="chooseAndUpload">
            Upload
          </button>
        </FileUpload>
      </div>
    );
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ updateOverview }, dispatch);
}

export default connect(null, mapDispatchToProps)(Header);

Component where data is shown:

import React, { Component } from 'react';
import { connect } from 'react-redux';

class Overview extends Component {
  renderContent() {
    console.log(this.props.overview);
    if (!this.props.overview) {
      return <div> Upload file!</div>;
    }
    return this.props.overview;
  }
  render() {
    return (
      <div>
        <h1>Overview</h1>
        {this.renderContent()}
      </div>
    );
  }
}
function mapStateToProps({ overview }) {
  return { overview };
}
export default connect(mapStateToProps)(Overview);

Action creator:

import { FETCH_OVERVIEW } from './types';

export function updateOverview(data) {
  return { type: FETCH_OVERVIEW, payload: data };
}

reducer index.js

import { combineReducers } from 'redux';
import overviewReducer from './overviewReducer';

export default combineReducers({
  overview: overviewReducer
});

overviewReducer.js

import { FETCH_OVERVIEW } from '../actions/types';
export default function(state = null, action) {
  switch (action.type) {
    case FETCH_OVERVIEW:
      return action.payload;
    default:
      return state;
  }
}

The only use case for bindActionCreators is when you want to pass some action creators down to a component that isn't aware of Redux, and you don't want to pass dispatch or the Redux store to it.

Your Header component already knows how to create action. Considering the your Home component need ,your don't need of bindActionCreators .

The correct way to do this.

const mapDispatchToProps = dispatch => {
    return {
        callUpdateOverview: () => {
            dispatch({ updateOverview });
        }
    }
}

And in the Header render method :

this.props.updateOverview(res.data);

EDIT :

In your Home Component render method,

       const homeThis = this; //save `this` object to some variables
       ^^^^^^^^^^^^^^^^^^^^^^

       const options = {
            baseUrl: ..,
            chooseAndUpload: ..,
            uploadSuccess: function (res) {
                homeThis.props.callUpdateOverview();// call using `homeThis`          
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            }
        };

In your code, you are calling

updateOverview(res.data);

actually which should be called like,

this.props.updateOverview(res.data);

Because, the redux will listen only to the dispatch bound actions, so to enable that, we use connect function from react-redux package, so that redux will know to update itself upon the action execution.

connect will bind your action to the component props on this.props , so it is very essential to use this.props.action() and not just action()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM