gpt4 book ai didi

javascript - 从action发送的数据没有被reducer接收到

转载 作者:行者123 更新时间:2023-12-03 00:27:42 26 4
gpt4 key购买 nike

我正在我的 React 应用程序中使用 redux。我正在尝试从我的 reducer 获取数据,但是当我尝试这样做时。我收到一些错误。

Uncaught Error: Given action "RECEIVE_CATEGORY_NAME", reducer "categoriesReducer" returned undefined. To ignore an action, you must explicitly return the previous state. If you want this reducer to hold no value, you can return null instead of undefined.

编写的逻辑在fluencersNameReducer的情况下工作正常,但在categoriesReducer的情况下显示错误home_reducer.js

import { RECEIVE_INFLUENCERS_NAME, RECEIVE_CATEGORY_NAME } from './home_actions';

export const influencersNameReducer = (state = [], { type, influencers }) => {
console.log(influencers)
return type === RECEIVE_INFLUENCERS_NAME ? influencers : state
}


export const categoriesReducer = (state = [], { type, category }) => {
console.log(type, category)
return type === RECEIVE_CATEGORY_NAME ? category : state
}

home_actions.js

export const RECEIVE_INFLUENCERS_NAME = 'RECEIVE_INFLUENCERS_NAME'
export const RECEIVE_CATEGORY_NAME = 'RECEIVE_CATEGORY_NAME';

const receiveInfluencersName = influencers => ({ type: RECEIVE_INFLUENCERS_NAME, influencers })

const receiveCategoryName = categories => ({ type: RECEIVE_CATEGORY_NAME, categories })

export const fetchInfluencers = _ => dispatch => {
$.ajax({
method: 'get',
url: 'vip_api/influencers',
data: { name: _ },
success(influencers) {
dispatch(receiveInfluencersName(influencers))
},
error({ responseJSON, statusText }) {
dispatch(receiveServerErrors(responseJSON || [statusText]))
}
})
}

export const fetchCategories = _ => dispatch => {
$.ajax({
method: 'get',
url: 'vip_api/categories',
data: { name: _ },
success(categories) {
dispatch(receiveCategoryName(categories))
},
error({ responseJSON, statusText }) {
dispatch(receiveServerErrors(responseJSON || [statusText]))
}
})
}

store.js

import {influencersNameReducer, categoriesReducer} from './Vvip/Home/home_reducer';
import { composeWithDevTools } from 'redux-devtools-extension';

const reducer = combineReducers({
categoriesReducer,
influencersNameReducer,
})

const composeEnhancers = composeWithDevTools({
// Specify name here, actionsBlacklist, actionsCreators and other options if needed
});
export default (state = {}) => (
createStore(reducer, state, composeEnhancers(applyMiddleware(errorMiddleware, timeoutMiddleware, thunk)))
)

index.js

import React, { Component } from 'react'
import Select, { components } from 'react-select'
import DateRange from '../../shared/_date_range';
import moment from 'moment';
import {ethnicities, ageRanges, isoCountries} from '../../constants';
import { connect } from 'react-redux';
import {fetchInfluencers, fetchCategories} from './home_actions';

class InfluencersForm extends Component {

constructor() {
super();
this.state = {
demography: null,
dates : {
startDate: moment(),
endDate: moment()
},
influencersName: [],
}
}

handleInfluencerName = event => {
this.props.dispatch(fetchInfluencers(event))
}

handleSelectedInfluencer = event => {
console.log(event)
this.setState({
isMenuOpenInfluencer : false
})
}
componentWillReceiveProps(newProps) {
console.log(newProps);
if (newProps.influencersNameReducer && newProps.influencersNameReducer.length) {
this.setState({
influencersName: newProps.influencersNameReducer.map((influencer, index) => {
return ({ value: influencer, label: influencer })
}),
})
}
}

handleInfluencerType = event => {
console.log(event)
}

handleInfluencerCountry = event => {
console.log(event)
}

handleInfluencerSubscribers = event => {
console.log(event)
}

handleInfluencerVideosCreated = event => {
console.log(event)
}

handleInfluencerCategory = event => {
console.log(event)
this.props.dispatch(fetchCategories(event))
}

onDemographyChange = event => {
console.log(event.currentTarget.value)
this.setState({
demography: event.currentTarget.value
})
}

handleInfluencerAge = event => {
console.log(event)
}

handleInfluencerGender = event => {
console.log(event)
}

handleInfluencerEthnicity = event => {
console.log(event)
}

updateDates = event => {
console.log(event)
this.setState({
dates: event
})
}
render() {
const influencersType = [
{ value: 'a', label: 'Type A' },
{ value: 'b', label: 'Type B' },
{ value: 'c', label: 'Type C' }
]

const influencersCategory = [
{ value: 'a', label: 'Type A' },
{ value: 'b', label: 'Type B' },
{ value: 'c', label: 'Type C' }
]

const influencersAge = ageRanges.map(age => ({ value: age, label: age }))

const influencersGender = [
{ value: 'male', label: 'Male' },
{ value: 'female', label: 'Female' }
]

const influencersKeywords = [
{ value: 'youtuber', label: 'Youtuber' },
{ value: 'vlogger', label: 'Vlogger' }
]

const influencersCountry = Object.keys(isoCountries).map(code => ({ value: code, label: isoCountries[code] }))

const DropdownIndicator = (props) => {
return components.DropdownIndicator && (
<components.DropdownIndicator {...props}>
<i className="fa fa-search" aria-hidden="true" style={{ position: 'initial', color: 'black' }}></i>
</components.DropdownIndicator>
);
};
return (
<div className='home-forms influencer-form'>
<div className='display-flex'>
<Select
options={this.state.influencersName}
onChange={this.handleSelectedInfluencer}
closeMenuOnSelect = {true}
isSearchable={true}
components={{ DropdownIndicator }}
onInputChange = {this.handleInfluencerName}
placeholder={'Start Typing Influencers Name'}
classNamePrefix="vyrill"
className="influencers influencers-icon-name" />

<Select
options={influencersType}
onChange={this.handleInfluencerType}
placeholder='Type of Influencers'
classNamePrefix="vyrill"
className="influencers influencers-icon-type" />

<Select
options={influencersCountry}
onChange={this.handleInfluencerCountry}
isSearchable={true}
components={{ DropdownIndicator }}
placeholder='Start Typing Country'
classNamePrefix="vyrill"
className="influencers influencers-icon-country" />
</div>
<div className='display-flex' style={{ marginTop: 32 }}>
<Select
options={influencersType}
onChange={this.handleInfluencerSubscribers}
placeholder='Number of Subscribers'
classNamePrefix="vyrill"
className="influencers influencers-icon-type" />

<Select
options={influencersType}
onChange={this.handleInfluencerVideosCreated}
placeholder='Number of Videos Created'
classNamePrefix="vyrill"
className="influencers influencers-icon-videos-created" />

<Select
options={influencersCategory}
onChange={this.handleInfluencerCategory}
onInputChange = {this.handleInfluencerCategory}
isSearchable={true}
components={{ DropdownIndicator }}
placeholder='Start Typing Category'
classNamePrefix="vyrill"
className="influencers influencers-icon-country influencers-icon-category" /> {/* remove influencers-icon-country later */}
</div>
<div style={{ marginTop: 50 }}>
<div className="display-flex">
<div className="icon-subscribers" style={{ marginTop: 4 }}></div>
<div style={{ fontWeight: 700, marginTop: 4 }}>Demographics</div>
<div className="radio-container">
<label>
<div style={{ fontSize: 14, marginTop: 4 }}>By influencers</div>
<input
type="radio"
name="demographics"
value="influencers"
checked={this.state.demography === 'influencers'}
onChange={this.onDemographyChange} />
<span className="custom-radio">
</span>
</label>
</div>
<div className="radio-container">
<label>
<div style={{ fontSize: 14, marginTop: 4 }}>By people in videos</div>
<input
type="radio"
name="demographics"
value="people in videos"
checked={this.state.demography === 'people in videos'}
onChange={this.onDemographyChange} />
<span className="custom-radio"></span>
</label>
</div>
</div>
</div>
<div className="display-flex" style={{ marginTop: 40 }}>
<Select
options={influencersAge}
onChange={this.handleInfluencerAge}
placeholder='Age'
classNamePrefix="vyrill"
className="influencers" />
<Select
options={influencersGender}
onChange={this.handleInfluencerGender}
placeholder='Gender'
classNamePrefix="vyrill"
className="influencers" />
<Select
options={ethnicities}
onChange={this.handleInfluencerEthnicity}
placeholder='Ethnicity'
classNamePrefix="vyrill"
className="influencers" />
</div>
<div style={{marginTop: 50}}>
<div style={{display: 'inline'}}>Contains keywords (in transcript):</div>
<span className="icon-info"></span>
<Select
options={influencersKeywords}
onChange={this.handleInfluencerName}
isSearchable={true}
classNamePrefix="vyrill"
placeholder= {" "}
className="influencers influencers-keywords"
styles = {{marginTop: 10}}/>
</div>
<div style={{marginTop: 50}} className="date-picker">
<div>Posted content time range</div>
<DateRange dates={ this.state.dates } updateDates={ this.updateDates }/>
<div className="icon-arrow-right"></div>
</div>
</div>
)
}
}

const mapStateToProps = ({ influencersNameReducer, categoriesReducer }) => ({
influencersNameReducer,
categoriesReducer
})

export default connect(mapStateToProps)(InfluencersForm)

最佳答案

您需要将您的 reducer 修改为:

export const influencersNameReducer = (state = [], { type, influencers }) => {
switch(type) {
case RECEIVE_INFLUENCERS_NAME:
return influencers;
default:
return state;
}
}
export const categoriesReducer = (state = [], { type, category }) => {
switch(type) {
case RECEIVE_CATEGORY_NAME:
return category;
default:
return state;
}
}

对于每个操作,调度程序都会前往每个 reducer 。由于在您的代码中,influencersNameReducer reducer 没有对 RECEIVE_CATEGORY_NAME 类型执行任何操作,因此返回 undefined。所以你得到了错误。使用 switch case 就是实现此目的的方法。

关于javascript - 从action发送的数据没有被reducer接收到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54022480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com