简体   繁体   English

React / Redux TypeError:this.state.dryRedBottles.map不是一个函数

[英]React/Redux TypeError: this.state.dryRedBottles.map is not a function

I have a container component that fetches data to a Rails API but can't successfully iterator over that data without getting the following error; 我有一个容器组件,该组件可以将数据获取到Rails API,但无法成功迭代该数据,而不会出现以下错误;

TypeError: this.state.dryRedBottles.map is not a function

This was caused by the following code; 这是由以下代码引起的;

    render() {

    let searchResults = this.state.dryRedBottles.map((bottle) =>  <SearchResults key={bottle} name={bottle}/>)

As you can see in the code above, I am setting a variable equal to an iteration over this.state.dryRedBottles, which should map every bottle object to the presentational component SearchResults. 如您在上面的代码中看到的,我在this.state.dryRedBottles上设置了一个等于迭代的变量,该变量应将每个瓶子对象映射到表示性组件SearchResults。

I also created a function, generateSearchResults to debug this.props and this.state. 我还创建了一个函数generateSearchResults来调试this.props和this.state。 this.state.dryRedBottles is by default an empty array, but it's updated to be an array of objects. 默认情况下,this.state.dryRedBottles是一个空数组,但已更新为对象数组。 Since iterators like .map or .forEach only work on arrays, I tried to mitigate this on my Rails server; 由于.map或.forEach之类的迭代器仅适用于数组,因此我尝试在Rails服务器上减轻这种情况。

def create 
    @wine_bottles = WineBottle.all 

    if params[:dryRedBottles][:fetchingRedDry] == true
        @red_dry_bottles = []

        @wine_bottles.each do |bottle|
            if (bottle.w_type == 'red') & (bottle.dry == true)
                bottle = [bottle] if !bottle.is_a?(Array)
                @red_dry_bottles.push(bottle)
            end 
        end
        render json: @red_dry_bottles
    else
        nil;
    end 
end 

I made sure each JSON object was push inside of an array, so at least this.state.dryRedBottles would return this; 我确保每个JSON对象都被推入数组内部,因此至少this.state.dryRedBottles将返回此值; [[{}], [{}], [{}]]. [[{}],[{}],[{}]]。

My question is: what is causing this error? 我的问题是:什么原因导致此错误? What workarounds can I leverage to successfully use searchResults? 我可以利用哪些解决方法来成功使用searchResults?

Below is my container component in its full glory; 以下是我的容器组件的全部功能;

class Red extends Component {

    constructor(props) {
        super(props);

        this.state = {
            // helps monitor toggling
            redDryClick: false,
            redBothClick: false,
            redSweetClick: false,
            fetchingRedDry: false,
            fetchingRedSweet: false,

            dryRedBottles: []
        };
    };

    handleSweetRequest = (event) => {
        event.preventDefault();

        this.setState(prevState => ({
            redDryClick: !prevState.redDryClick,
            redBothClick: !prevState.redBothClick
          }));
    }

    handleDryRequest = (event) => {
        event.preventDefault();
        this.setState(prevState => ({
            redSweetClick: !prevState.redSweetClick,
            redBothClick: !prevState.redBothClick,
            fetchingRedDry: !prevState.fetchingRedDry
        }));
    }

    componentDidUpdate(){
        if (this.state.fetchingRedDry === true) {
            let redDryState = Object.assign({}, this.state);
            this.props.fetchDryReds(redDryState);

            // this.props.dryRedBottles.length > this.state.dryRedBottles.length

            if (this.props.dryRedBottles !== this.state.dryRedBottles ) {
                this.setState({ dryRedBottles: this.props.dryRedBottles });
            }
        }
        debugger;
    }

    handleBothRequest = (event) => {
        event.preventDefault();

        this.setState(prevState => ({
            redDryClick: !prevState.redDryClick,
            redSweetClick: !prevState.redSweetClick
        }));
    }

    generateSearchResults = () => {
        debugger;
        if ( Array.isArray(this.props.dryRedBottles) ) {
            this.props.dryRedBottles.map((bottle) => {
                debugger;
                return bottle;
            })
        }
    }

    render() {

        let searchResults = this.state.dryRedBottles.map((bottle) =>  <SearchResults key={bottle} name={bottle}/>)

        return (
            <div>
                <h2>Welcome to... Red</h2>

                <FormControlLabel
                    control={
                    <Switch
                        // configuring @material-ui Switch componanet
                        value="hidden"
                        color="primary"
                        id="redSweet"
                        disableRipple

                        // handles previous State + redux + API call
                        onChange={this.handleSweetRequest}
                        disabled={this.state.redSweetClick}
                    />
                    }
                    label="Sweet"
                />


                <FormControlLabel
                    control={
                    <Switch
                        // configuring @material-ui Switch componanet
                        // value="hidden"
                        value="RedDry"
                        color="primary"
                        id="redDry"
                        disableRipple

                        // handles previous State + redux + API call
                        onChange={(event) => this.handleDryRequest(event)}
                        disabled={this.state.redDryClick}
                    />
                    }
                    label="Dry"
                />


                <FormControlLabel
                    control={
                    <Switch
                        // configuring @material-ui Switch componanet
                        value="hidden"
                        color="primary"
                        id="redBoth"
                        disableRipple

                        // handles previous State + redux + API call
                        onChange={this.handleBothRequest}
                        disabled={this.state.redBothClick}
                    />
                    }
                    label="Both"
                />

                <div>
                    {searchResults}
                </div>
            </div>
        )
    }
}

function mapStateToProps(state) {
    return {
        dryRedBottles: state.redWineReducer
    };
}

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators({
        fetchDryReds: fetchDryReds
    }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(Red);

Below is my actionCreator; 以下是我的actionCreator;

    export function fetchDryReds(redDryState) {
  return (dispatch) => {
    // debugger;
    // dispatch({ type: 'LOADING_DRY_REDS' });
    return fetch('http://localhost:3001/wine_bottles', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'},
      body: JSON.stringify({dryRedBottles: redDryState})})
      .then(response => response.json())
      .then(dryRedBottles => {
        dispatch({ type: 'FETCH_DRY_REDS', dryRedBottles })});
  }
}

Below is my reducer; 下面是我的减速器;

    export default function redWineReducer (state={}, action) {
switch (action.type) {
    case 'FETCH_DRY_REDS':
        // debugger;
        return action.dryRedBottles
    default: 
        return state;
}

} }

This is the array of objects I am attempting to iterate over; 这是我尝试迭代的对象数组;

the initial state is an object... not an array so: 初始状态是一个对象...而不是数组,因此:

export default function redWineReducer (state={}, action) {

change it to: 更改为:

export default function redWineReducer (state=[], action) {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM