我正在以自己的方式学习一些反应+ 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调用的结果后如何填充它。
答案 0 :(得分:0)
我在这段代码中看到两个问题
首先,当您只有一个reducer时,不需要使用combineReducers
。只需保持简单,只有在绝对必要时才增加复杂性。而不是combineReducers
export default jokesBySearch
如果您确实使用combineReducers
,请注意它对您的州的影响
其次,不需要在这里使用bindactioncreators
,只需调度操作(并且不要忘记传递term
)。
function mapDispatchToProps(dispatch) {
return{
fetchJokes: (term) => dispatch(fetchJokes(term))
}
}
当您需要使用bindactioncreators(非常罕见的用例)时,请参阅此处 一般来说,学习像redux这样的库的好方法只是使用核心功能,直到遇到问题,然后才增加复杂性。