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.