Reputation: 4028
Trying to mess around with react and redux to fetch a list of files from an API.
When looking in the react dev tools I can see my data there but it is not being rendered.
actions.js
export const requestFiles = ({
type: REQUEST_FILES,
});
export const receiveFiles = (json) => ({
type: RECEIVE_FILES,
files: json,
receivedAt: Date.now()
});
export const fetchFiles = (dispatch) => {
dispatch(requestFiles);
return fetch('/api/files')
.then(response => response.json())
.then(json => dispatch(receiveFiles(json)))
};
The action gets data from JSON
reducer.js
const files = (state = {
isFetching: false,
items: []
}, action) => {
switch (action.type) {
case REQUEST_FILES:
return {
...state,
isFetching: true,
};
case RECEIVE_FILES:
return {
...state,
isFetching: false,
items: action.files,
lastUpdated: action.receivedAt
};
default:
return state
}
};
const filesUploaded = (state = { }, action) => {
switch (action.type) {
case RECEIVE_FILES:
case REQUEST_FILES:
return {
...state,
items: files(state[action], action)
};
default:
return state
}
};
const rootReducer = combineReducers({
filesUploaded
});
export default rootReducer
App.js
class App extends Component {
static propTypes = {
files: PropTypes.array.isRequired,
isFetching: PropTypes.bool.isRequired,
dispatch: PropTypes.func.isRequired
};
componentDidMount() {
const {dispatch} = this.props;
dispatch(fetchFiles);
}
handleChange = nextSubreddit => {
};
render() {
const {files, isFetching} = this.props;
const isEmpty = files.length === 0;
console.log(`Files is empty ${isEmpty}`);
return (
<div>
<h1>Uploadr</h1>
{isEmpty
? (isFetching ? <h2>Loading...</h2> : <h2>No files.</h2>)
: <div style={{opacity: isFetching ? 0.5 : 1}}>
<Files files={files}/>
</div>
}
</div>
)
}
}
const mapStateToProps = state => {
const {uploadedFiles} = state;
const {isFetching, items: files} = uploadedFiles
|| {isFetching: true, items: []};
console.log(files);
return {
files,
isFetching,
}
};
The data being received in the action but I am not sure if it is getting stored or if the problem is accessing it from the redux store.
The files property is still zero on the App component as shown in the screenshot above.
Any ideas?
Upvotes: 1
Views: 8915
Reputation: 1368
Delete your filesUploaded
reducer. You don't need it. Instead, just use the files
reducer:
const rootReducer = combineReducers({
files,
});
Please note, the slice of state you are interested in will be called files
. Change your mapStateToProps
function to this:
const mapStateToProps = state => {
const {isFetching, items: files} = state.files
console.log(files);
return {
files,
isFetching,
}
};
You can see here, we grab the files
slice of state and pass that into your component.
Upvotes: 1
Reputation: 1148
Your filesUploaded
reducer does not make any sense. I'm not sure what filesUploaded
is even supposed to be doing. Your files
reducer looks like a normal reducer. It seems like you could just delete filesUploaded
and everything would be fine.
In particular, filesUploaded
is calling files(state[action], action)
. action
is an object. What is state[SOME_OBJECT]
supposed to be? Because it's being parsed as state['[object Object]']
which is surely undefined and never would become defined.
Your files
reducer also has an items
parameter that is just never used. A reducer should only have two parameters: state and action. Drop the items parameter.
Your mapStateToProps
is looking for state.uploadedFiles
, but your reducer is called filesUploaded
. It should be state.filesUploaded
(or if you replace it with the files
reducer, just state.files
).
mapStateToProps
will not need || {isFetching: true, items: []}
since you have an initial state on your files
reducer.
Upvotes: 1