TypeError:componentDidMount内部的defaultPieces不是函数

时间:2018-07-03 17:09:42

标签: redux react-redux

在我的行业可能组件中,我从动作/索引文件中导入了一些异步函数,当我在componentDidMount内部调用这些函数时,我得到的错误是:defaultPieces不是一个函数。

以下是我的MayaMatches组件和actions / index.js文件的内容:

为了简洁起见,我尽力添加了与主要问题相关的所有内容。

PossibleMatches.js

import { connect } from 'react-redux';
import {arrangePieces, defaultPieces, setEvaluatedPiece, getCorrespondingPieces} from '../actions/index';

      constructor(props){
        super(props);

        const initialState = {
            currentComponent: {whichPiece: {whichType: null, currentUpperComponent: null, currentLowerComponent: null}},
            UpperComponents: this.props.UpperComponents,
            LowerComponents: this.props.LowerComponents,
            UpperComponentEnabled: false,
            LowerComponentEnabled: false,
            isFetched: false,
            isFetching: true
        }

        this.state = {
           ...initialState
        }   

        this.residingUpperComponent = createRef();
        this.residingLowerComponent = createRef();
    //Also need to this.prop.setEvaluatedPiece based off of this.props.setCurrentComponent if callback from Lower or Upper Components elapses time
        this.setNewPiece = this.setNewPiece.bind(this);

        this.renderDecision = this.renderDecision.bind(this);
    }


    async componentDidMount(){

       const {store} = this.context;
       let stateRef = store.getState();

        const { defaultPieces, arrangePieces } = this.props;

       try {
           const summon = () => { defaultPieces();
                                  arrangePieces();}
           await summon();
        } catch(error){
           throw Error(error);
        }

        console.log("AFEWOVMAOVHIE")
        this.setState({isFetched: true, isFetching: false});
    }

    renderDecision(){

    const { currentComponent, LowerComponentEnabled, UpperComponentEnabled, isFetching, isFetched} = this.state;
    const { suggestedBottoms, suggestedTops, UpperComponents, LowerComponents } = this.props;

    if (isFetching){
         return (<div className='activityLoader'>
                    <ActivityIndicator number={3} duration={200} activeColor="#fff" borderWidth={2} borderColor="50%" diameter={20}/>
                 </div>);
    } else if (isFetched){
            return (

                <div className = "PossibleMatches_Container">
                       <i className = 'captureOutfit' onClick = {this.snapshotMatch}></i> 
                       <TransitionGroup component = {PossibleMatches}>
                         ** ** ** {UpperComponents.map((component) => {                             
                                    return (<UpperComponent key={component.created_at} id={component.id} 
                                               switchComponent={this.switchFocus} 
                                               setCurrentPiece={this.setNewPiece} 
                                               evaluatePiece={this.isOppositeComponentSuggested}
                                               image={component.image}
                                               toggleToPiece = {() => {if (LowerComponentEnabled === false){this.setState({LowerComponentEnabled: true})} else return; this.setState({currentLowerComponent: suggestedBottoms[0]})}}
                                               isLowerComponentEnabled = {LowerComponentEnabled}
                                               ref = {this.residingUpperComponent}
                                               className = {currentComponent.whichPiece.whichType === 'match' ? 'PossibleMatches_Container' : currentComponent.whichPiece.whichType === 'bottom' ? 'standalonePiece' : 'standalonePiece'}/>
                                            )
                                    })
                            }
                        </TransitionGroup>
                        <TransitionGroup component = {PossibleMatches}>
                            {LowerComponents.map((component) => {
                                return  (<LowerComponent key={component.created_at} id={component.id} 
                                           setCurrentPiece = {this.setNewPiece} 
                                           evaluatePiece={this.isOppositeComponentSuggested}
                                           image={component.image}
                                           toggleToPiece = {() => {if (UpperComponentEnabled === false){this.setState({UpperComponentEnabled: true})} else return; this.setState({currentUpperComponent: suggestedTops[0]})}}              
                                           switchComponent = {this.switchFocus}
                                           isUpperComponentEnabled = {UpperComponentEnabled}
                                           ref = {this.residingLowerComponent}
                                           className = {this.state.currentComponent.whichPiece.whichType === 'match' ? 'PossibleMatches_Container' : this.state.currentComponent.whichPiece.whichType === 'bottom' ? 'standalonePiece' : 'standalonePiece'}/>)                                                  

                                })
                          }
                        </TransitionGroup>
                </div>
            )
    }
}

render(){


    return(  

            <div className = 'GorClothingContainer'>
              <Wardrobe upperComponent={this.state.currentComponent.whichPiece.currentUpperComponent} lowerComponent={this.state.currentComponent.whichPiece.currentLowerComponent} enableCapture={(snapshot) => this.snapshotMatch = snapshot} />
              {this.renderDecision()}
            </div>
        );
}

function mapStateToProps(state){
    const { UpperComponents, LowerComponents, contemplated_piece, extraTops, extraBottoms, standaloneBottoms, standaloneTops, suggestedBottoms, suggestedTops } = state.possibleMatches;
    return {UpperComponents, LowerComponents, contemplated_piece, extraTops, extraBottoms, standaloneBottoms, standaloneTops, suggestedBottoms, suggestedTops };
 }

export default connect(mapStateToProps, {defaultPieces, arrangePieces, getCorrespondingPieces, setEvaluatedPiece})(PossibleMatches)

在我的actions / index.js内部

export function defaultPieces(){
    return function(dispatch){
        fetch(`${API_URL}/possible_matches/setup_possible_matches`, {
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            }
        }).then((res) => res.json())
        .then((json) => {
            console.log('defaultPieces: ', json);
            dispatch(getInitialPieces(json))
        })
    }
}

export function getInitialPieces(request){
    return {
        type: INITIAL_PIECES,
        payload: request
    }
}

在“可能的匹配”简化工具内:

import {INITIAL_PIECES, GET_ANCILLARY_PIECES, ORGANIZE_PIECES, SET_CONTEMPLATED_PIECE} from '../actions/types';

const initialState = {
     UpperComponents: [],
     LowerComponents: [],
     contemplated_piece: null,
     extraTops: [],
     extraBottoms: [],
     standaloneTops: [],
     standaloneBottoms: [],
     suggestedTops: [],
     suggestedBottoms: []
}

export default function(state = initialState, action){


switch(action.type){
    case INITIAL_PIECES:
        return {...state, {contemplated_piece: action.payload.contemplated_piece,
                          extraTops: action.payload.extra_tops,
                          extraBottoms: action.payload.extra_bottoms,
                          standaloneTops: action.payload.standalone_tops,
                          standaloneBottoms: action.payload.standalone_bottoms,
                          suggestedTops: action.payload.suggested_tops,
                          suggestedBottoms: action.payload.suggested_bottoms}
    case GET_ANCILLARY_PIECES:
           return {...state, extraTops: action.payload.extra_tops,
                             extraBottoms: action.payload.extra_bottoms,
                             standaloneTops: action.payload.standalone_tops,
                             standaloneBottoms: action.payload.standalone_bottoms,
                             suggestedTops: action.payload.suggested_tops,
                             suggestedBottoms: action.payload.suggested_bottoms}
        case ORGANIZE_PIECES:
               return {...state, UpperComponents: action.payload.UpperComponents,
                                 LowerComponents: action.payload.LowerComponents}           
        case SET_CONTEMPLATED_PIECE:
           return {...state, contemplated_piece: action.payload.contemplated_piece}
        default:
            return state;

}

}

因为defaultPieces可能不是对MayaMatches组件有效的函数,所以它会干扰对来自mapStateToProps函数的UpperComponents道具的解释(上面用*表示)。

从rangingPieces和defaultPieces方法注销到控制台的json是特有的:

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:0)

这是一个奇怪的修复,但是我基本上需要在ComponentDidMount中设置条件,以根据UpperComponents的状态(相对于this.props.arrangePieces()返回的状态)暂停程序。

    if (UpperComponents.length === 0){
        return;
    } else {
        this.setState({isFetched: true, isFetching: false});
    }

由于组件已转售,所以我认为添加一个componentWillRecieveProps生命周期方法来处理传入的道具是理想的:

componentWillReceiveProps(nextProps){

    if (nextProps.contemplated_piece !== this.props.contemplated_piece){
        if (nextProps.contemplated_piece.merch_type === 'top'){
            this.setState({currentLowerComponent: nextProps.suggestedBottoms[0], 
                    currentUpperComponent: nextProps.contemplated_piece});
        }
        else if (nextProps.contemplated_piece.merch_type === 'bottom'){
            this.setState({currentLowerComponent: nextProps.contemplated_piece,
                    currentUpperComponent: nextProps.suggestedTops[0]});
        }
    }
    else {
        return null;
    }
}