admin管理员组

文章数量:1023187

I'm new with Redux Thunk and I'm having problems with dispatch an action after fetching async call by click on button ponent.

actions.js

import fetch from 'isomorphic-fetch'

export const getPosts = (json) => {
    return {
        type: constant.GET_POSTS,
        payload: {
            data: json
        }
    }
}

export const loadPosts () => {
    return (dispatch) => {
        return fetch('')
            .then(res => {
                res.json()
            }).then(json => {
                dispatch(getPosts(json))
            })
    }
}

button.js

class Button extends React.Component {

    clicked(){
        console.log(this.props.loadJsonPosts()) // got undefined here
    }
    render() {
        return(
            <button onClick={this.clicked.bind(this)}>click</button>
        )
    }
}

buttonContainer.js

import connect from 'react-redux/lib/ponents/connect'
import { loadPosts } from '../actions/actions.js'
import Button from '../ponents/Button'

function mapDispatchToProps(dispatch) {
    return {
        loadJsonPosts: () => { dispatch(loadPosts()) }
    }
}

export default connect(null, mapDispatchToProps)(Button)

reducer.js

import * as constant from '../constants/index'

let initialState = { postList: [] }

const reducer = (state = initialState, action) => {

    switch (action.type) {
        case constant.GET_POSTS: //here i call my loadPosts action
            state = Object.assign({}, { postList: [{ post: action.data }] })
            break;
        default:
            break;
    }

    return state
}

export default reducer

App.jsx

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Main from './ponents/Main'
import thunk from 'redux-thunk'
import { createStore, applyMiddleware  } from 'redux'
import { Provider } from 'react-redux'
import reducer from './reducers/reducer'
const store = createStore(
    reducer,
    applyMiddleware(thunk)
)

class App extends Component {
    render() {
        return(
            <Provider store={store}>
                <Main />
            </Provider>
        )
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('app')
)

I can't figure out why i get undefined, maybe I've missed something or I've wrong the approach

I'm new with Redux Thunk and I'm having problems with dispatch an action after fetching async call by click on button ponent.

actions.js

import fetch from 'isomorphic-fetch'

export const getPosts = (json) => {
    return {
        type: constant.GET_POSTS,
        payload: {
            data: json
        }
    }
}

export const loadPosts () => {
    return (dispatch) => {
        return fetch('https://jsonplaceholder.typicode./posts')
            .then(res => {
                res.json()
            }).then(json => {
                dispatch(getPosts(json))
            })
    }
}

button.js

class Button extends React.Component {

    clicked(){
        console.log(this.props.loadJsonPosts()) // got undefined here
    }
    render() {
        return(
            <button onClick={this.clicked.bind(this)}>click</button>
        )
    }
}

buttonContainer.js

import connect from 'react-redux/lib/ponents/connect'
import { loadPosts } from '../actions/actions.js'
import Button from '../ponents/Button'

function mapDispatchToProps(dispatch) {
    return {
        loadJsonPosts: () => { dispatch(loadPosts()) }
    }
}

export default connect(null, mapDispatchToProps)(Button)

reducer.js

import * as constant from '../constants/index'

let initialState = { postList: [] }

const reducer = (state = initialState, action) => {

    switch (action.type) {
        case constant.GET_POSTS: //here i call my loadPosts action
            state = Object.assign({}, { postList: [{ post: action.data }] })
            break;
        default:
            break;
    }

    return state
}

export default reducer

App.jsx

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Main from './ponents/Main'
import thunk from 'redux-thunk'
import { createStore, applyMiddleware  } from 'redux'
import { Provider } from 'react-redux'
import reducer from './reducers/reducer'
const store = createStore(
    reducer,
    applyMiddleware(thunk)
)

class App extends Component {
    render() {
        return(
            <Provider store={store}>
                <Main />
            </Provider>
        )
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('app')
)

I can't figure out why i get undefined, maybe I've missed something or I've wrong the approach

Share Improve this question edited Oct 13, 2016 at 9:38 Luca Mormile asked Oct 13, 2016 at 8:17 Luca MormileLuca Mormile 1,1876 gold badges19 silver badges37 bronze badges 1
  • Did you register your reducer in rootReducer? – Shota Commented Oct 13, 2016 at 8:53
Add a ment  | 

3 Answers 3

Reset to default 4

You forgot to return res.json() in actions.js for the next then block. it should be

export const loadPosts () => {
return (dispatch) => {
    return fetch('https://jsonplaceholder.typicode./posts')
        .then(res => {
            return res.json();
        }).then(json => {
            dispatch(getPosts(json))
        })
      }}

or you can skip the return statement by removing the blocks by writing .then(res => res.json())

I the same issue and found that ensuring the thunk middleware was first in my chain when creating the redux store allowed me to access the promise I was after rather than getting undefined,

store = createStore(
            rootReducer, 
            initialState,
            applyMiddleware(thunk, otherMiddleware1, otherMiddleware2)
        );

mapDispatchToProps should be like this:

function mapDispatchToProps(dispatch) {
return {
    // loadPosts instead of loadPosts()
    loadJsonPosts: () => { dispatch(loadPosts) }
} }

I'm new with Redux Thunk and I'm having problems with dispatch an action after fetching async call by click on button ponent.

actions.js

import fetch from 'isomorphic-fetch'

export const getPosts = (json) => {
    return {
        type: constant.GET_POSTS,
        payload: {
            data: json
        }
    }
}

export const loadPosts () => {
    return (dispatch) => {
        return fetch('')
            .then(res => {
                res.json()
            }).then(json => {
                dispatch(getPosts(json))
            })
    }
}

button.js

class Button extends React.Component {

    clicked(){
        console.log(this.props.loadJsonPosts()) // got undefined here
    }
    render() {
        return(
            <button onClick={this.clicked.bind(this)}>click</button>
        )
    }
}

buttonContainer.js

import connect from 'react-redux/lib/ponents/connect'
import { loadPosts } from '../actions/actions.js'
import Button from '../ponents/Button'

function mapDispatchToProps(dispatch) {
    return {
        loadJsonPosts: () => { dispatch(loadPosts()) }
    }
}

export default connect(null, mapDispatchToProps)(Button)

reducer.js

import * as constant from '../constants/index'

let initialState = { postList: [] }

const reducer = (state = initialState, action) => {

    switch (action.type) {
        case constant.GET_POSTS: //here i call my loadPosts action
            state = Object.assign({}, { postList: [{ post: action.data }] })
            break;
        default:
            break;
    }

    return state
}

export default reducer

App.jsx

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Main from './ponents/Main'
import thunk from 'redux-thunk'
import { createStore, applyMiddleware  } from 'redux'
import { Provider } from 'react-redux'
import reducer from './reducers/reducer'
const store = createStore(
    reducer,
    applyMiddleware(thunk)
)

class App extends Component {
    render() {
        return(
            <Provider store={store}>
                <Main />
            </Provider>
        )
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('app')
)

I can't figure out why i get undefined, maybe I've missed something or I've wrong the approach

I'm new with Redux Thunk and I'm having problems with dispatch an action after fetching async call by click on button ponent.

actions.js

import fetch from 'isomorphic-fetch'

export const getPosts = (json) => {
    return {
        type: constant.GET_POSTS,
        payload: {
            data: json
        }
    }
}

export const loadPosts () => {
    return (dispatch) => {
        return fetch('https://jsonplaceholder.typicode./posts')
            .then(res => {
                res.json()
            }).then(json => {
                dispatch(getPosts(json))
            })
    }
}

button.js

class Button extends React.Component {

    clicked(){
        console.log(this.props.loadJsonPosts()) // got undefined here
    }
    render() {
        return(
            <button onClick={this.clicked.bind(this)}>click</button>
        )
    }
}

buttonContainer.js

import connect from 'react-redux/lib/ponents/connect'
import { loadPosts } from '../actions/actions.js'
import Button from '../ponents/Button'

function mapDispatchToProps(dispatch) {
    return {
        loadJsonPosts: () => { dispatch(loadPosts()) }
    }
}

export default connect(null, mapDispatchToProps)(Button)

reducer.js

import * as constant from '../constants/index'

let initialState = { postList: [] }

const reducer = (state = initialState, action) => {

    switch (action.type) {
        case constant.GET_POSTS: //here i call my loadPosts action
            state = Object.assign({}, { postList: [{ post: action.data }] })
            break;
        default:
            break;
    }

    return state
}

export default reducer

App.jsx

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Main from './ponents/Main'
import thunk from 'redux-thunk'
import { createStore, applyMiddleware  } from 'redux'
import { Provider } from 'react-redux'
import reducer from './reducers/reducer'
const store = createStore(
    reducer,
    applyMiddleware(thunk)
)

class App extends Component {
    render() {
        return(
            <Provider store={store}>
                <Main />
            </Provider>
        )
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('app')
)

I can't figure out why i get undefined, maybe I've missed something or I've wrong the approach

Share Improve this question edited Oct 13, 2016 at 9:38 Luca Mormile asked Oct 13, 2016 at 8:17 Luca MormileLuca Mormile 1,1876 gold badges19 silver badges37 bronze badges 1
  • Did you register your reducer in rootReducer? – Shota Commented Oct 13, 2016 at 8:53
Add a ment  | 

3 Answers 3

Reset to default 4

You forgot to return res.json() in actions.js for the next then block. it should be

export const loadPosts () => {
return (dispatch) => {
    return fetch('https://jsonplaceholder.typicode./posts')
        .then(res => {
            return res.json();
        }).then(json => {
            dispatch(getPosts(json))
        })
      }}

or you can skip the return statement by removing the blocks by writing .then(res => res.json())

I the same issue and found that ensuring the thunk middleware was first in my chain when creating the redux store allowed me to access the promise I was after rather than getting undefined,

store = createStore(
            rootReducer, 
            initialState,
            applyMiddleware(thunk, otherMiddleware1, otherMiddleware2)
        );

mapDispatchToProps should be like this:

function mapDispatchToProps(dispatch) {
return {
    // loadPosts instead of loadPosts()
    loadJsonPosts: () => { dispatch(loadPosts) }
} }

本文标签: javascriptRedux thunk fetch return undefinedStack Overflow