Reactjs + Redux:在onClick异步调用后检索this.props值

时间:2018-04-18 06:27:02

标签: javascript reactjs react-redux

我正在以自己的方式学习一些反应+ redux-thunk并且我已经整理了一个简单的表单,它可以访问API并检索一些笑话。我的核心组件和代码:

容器/ AsyncApp.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import {bindActionCreators} from 'redux';

import SearchJokes from '../components/SearchJokes';
import Jokes from '../components/Jokes';
import {fetchJokes} from '../actions';

class AsyncApp extends Component {
    constructor(props) {
      super(props)
      this.handleSubmit = this.handleSubmit.bind(this)
      this.handleInput = this.handleInput.bind(this)
      this.state = {searchText: ''};
    }

    handleSubmit(e){
        e.preventDefault();
        //const {searchText} = this.props;
        console.log('button clicked ' + this.state.searchText);
        this.props.fetchJokes(this.state.searchText);
    }

    handleInput = (e) => {
        this.setState({
            searchText: e.target.value,
        })
    }

    render(){
        const { jokes, isFetching } = this.props
        return(
            <div>
                <SearchJokes
                    handleSubmit={this.handleSubmit}
                    onChange={this.handleInput}
                    searchText={this.state.searchText}
                />
                {jokes ? (<Jokes jokes={jokes}/>) : (<div></div>)}

            </div>
        )
    }

}

function mapStateToProps(state) {
    return {
        isFetching: state.isFetching,
        jokes: state.items
    }
}

function mapDispatchToProps(dispatch) {
    return{
        fetchJokes: bindActionCreators(fetchJokes, dispatch)
    }
}


export default connect(mapStateToProps, mapDispatchToProps)(AsyncApp)

操作/ index.js

export const REQUEST_JOKES = 'REQUEST_JOKES'
export const RECEIVE_JOKES = 'RECEIVE_JOKES'


function requestJokes(term) {
    return {
      type: REQUEST_JOKES,
      term
    }
  }

  function receiveJokes(term, json) {
    return {
      type: RECEIVE_JOKES,
      term,
      jokes: json.results.map(joke => joke)

    }
  }

  export function fetchJokes(term) {
    return dispatch => {
      dispatch(requestJokes(term))
      return fetch(`https://icanhazdadjoke.com/search?term=${term}`, {
        method: 'GET',
        headers: {
            'Accept': 'application/json'
          }
      }).then(response => response.json())
        .then(json => dispatch(receiveJokes(term, json)))
    }
  }

减速器/ index.js

import { combineReducers } from 'redux'
import {
  REQUEST_JOKES,
  RECEIVE_JOKES
} from '../actions'


function jokesBySearch(state = {}, action) {
    switch(action.type){
        case REQUEST_JOKES:
            return Object.assign({}, state, {isFetching: true, items: []})
        case RECEIVE_JOKES:
            return Object.assign({}, state, {
                isFetching: false,
                items: action.jokes,
            })
        default:
            return state
    }

}

const rootReducer = combineReducers({
    jokesBySearch,
  })

  export default rootReducer

表单组件工作,我可以看到作为操作的一部分返回的json数组。但是this.props.jokes的值在console.log中是空的或未定义的,我想知道如果返回API调用的结果后如何填充它。

this page

1 个答案:

答案 0 :(得分:0)

我在这段代码中看到两个问题 首先,当您只有一个reducer时,不需要使用combineReducers。只需保持简单,只有在绝对必要时才增加复杂性。而不是combineReducers

export default jokesBySearch

如果您确实使用combineReducers,请注意它对您的州的影响 其次,不需要在这里使用bindactioncreators,只需调度操作(并且不要忘记传递term)。

function mapDispatchToProps(dispatch) {
    return{
        fetchJokes: (term) => dispatch(fetchJokes(term))
    }
}

当您需要使用bindactioncreators(非常罕见的用例)时,请参阅此处 一般来说,学习像redux这样的库的好方法只是使用核心功能,直到遇到问题,然后才增加复杂性。