首页 文章

尝试在ComponentDidMount中填充具有异步承诺的道具

提问于
浏览
0

因此,在我不受控制的PossibleMatches组件中,我知道从React的工作方式来看,初始渲染阶段将发生空的prop值(如果这些prop值依赖于外部应用程序状态(mapStateToProps)),无论我是否有componentDidMount生命周期方法或构造函数设置 . 为此,我在componentDidMount中设置了一个promise,这样当我调度prop函数[defaultPieces,arrangePieces]时,我可以让UI渲染一个ActivityIndicator来指示当前正在获取的东西 . 问题是,当我从promise的成功阶段调用mapStateToProps时,我似乎无法获得mapStateToProps函数来理解状态 . 这里是:

class PossibleMatches extends Component {
    constructor(props){
        super(props);
    }

componentDidMount(props){
    return new Promise((resolve, reject) => {
        let state;
        let {defaultPieces, arrangePieces, isFetching} = this.props;
        let makeClothesAppear = function(){
            defaultPieces();
            arrangePieces();
            isFetching = true;
        }

        resolve(makeClothesAppear());
    }).then(function(state){
        mapStateToProps(state);
        this.props.isFetched = true
        this.props.isFetching = false;
    }).catch((error) => {
        console.log('FetchClothesError: ', error);
    })
}
}

How the UI would make a decision on what to display:

renderDecision(){

        const {UpperComponents, LowerComponents} = this.props;
        const {currentUpperComponent, currentLowerComponent} = this.state.currentComponent.whichPiece;
        const {LowerComponentEnabled, UpperComponentEnabled} = this.state;

        if (this.props.isFetching){
             return (<div className='activityLoader'>
                        <ActivityIndicator number={3} duration={200} activeColor="#fff" borderWidth={2} borderColor="50%" diameter={20}/>
                     </div>);
        } else if (this.props.isFetched){
                return (<div className = "PossibleMatches_Container">
                        <i className = 'captureOutfit' onClick = {this.snapshotMatch}></i> 
                            {UpperComponents.map((component) => {                               
                                    return (<UpperComponent key={component.createdAt} id={component.id} 
                                               switchComponent={this.switchFocus} 
                                               setCurrentPiece = {this.setNewPiece} 
                                               evaluatePiece={this.isOppositeComponentSuggested}
                                               image={component.image}
                                               toggleToPiece = {(LowerComponentEnabled) => {if (LowerComponentEnabled === false){this.setState({LowerComponentEnabled: true})}else{return;} this.setState({currentLowerComponent: this.props.suggestedBottoms[0]})}} 
                                               isLowerComponentEnabled={LowerComponentEnabled}
                                               ref={this.residingUpperComponent}
                                               className = {this.state.currentComponent.whichPiece.whichType === 'match' ? 'PossibleMatches_Container' : this.state.currentComponent.whichPiece.whichType === 'bottom' ? 'standalonePiece' : 'standalonePiece'}/>)
                                    })
                            }
                            {LowerComponents.map((component) => {
                                    return  (<LowerComponent key={component.createdAt} id={component.id} 
                                               setCurrentPiece = {this.setNewPiece} 
                                               evaluatePiece={this.isOppositeComponentSuggested}
                                               image={component.image}
                                               toggleToPiece={(UpperComponentEnabled) => {if (UpperComponentEnabled === false){this.setState({UpperComponentEnabled: true})}else{return;} this.setState({currentUpperComponent: this.props.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'}/>)                                                  
                                    })
                            }
                        </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>
            );
    }

My PossibleMatches Reducer

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 Object.assign({}, 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 Object.assign({}, 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 Object.assign({}, state, {UpperComponents: action.payload.UpperComponents},
                                               {LowerComponents: action.payload.LowerComponents})           
        case SET_CONTEMPLATED_PIECE:
           return Object.assign({}, state, {contemplated_piece: action.payload.contemplated_piece})
        default:
            return state;
    }
}

My combineReducers segment

import {combineReducers} from 'redux';

const allReducers = combineReducers({
 Playlist: PlaylistReducer,
 eventOptions: eventTicketReducer,
 possibleMatches: PossibleMatchesReducer,
 Intro: combineForms({
        basicUserInfo: BasicUserInfoState,
        GenderInfo: GenderInfoState,
        ContactInfo: ContactInfoState
       }, 'Intro'),
 routing: routerReducer,
 form: formReducer
});

Prop Values:

PossibleMatches.defaultProps = {
    isFetching: true,
    isFetched: false
}

My mapStateToProps function

function mapStateToProps(state){

            return {UpperComponents: state.possibleMatches.UpperComponents,
                    LowerComponents: state.possibleMatches.LowerComponents,
                    contemplatedPiece: state.possibleMatches.contemplated_piece,
                    extraTops: state.possibleMatches.extraTops,
                    extraBottoms: state.possibleMatches.extraBottoms,
                    standaloneTops: state.possibleMatches.standaloneTops,
                    standaloneBottoms: state.possibleMatches.standaloneBottoms,
                    suggestedTops: state.possibleMatches.suggestedTops,
                    suggestedBottoms: state.possibleMatches.suggestedBottoms}
}

function mapDispatchToProps(dispatch){
      return {
        defaultPieces: () => {
          dispatch(defaultPieces())
        },
        arrangePieces: () => {
            dispatch(arrangePieces())
        },
        getCorrespondingPieces: () => {
            dispatch(getCorrespondingPieces())
        },
        setEvaluatedPiece: () => {
            dispatch(setEvaluatedPiece())
        }
      }
    }

export default connect(mapStateToProps, mapDispatchToProps)(PossibleMatches)

我的问题是:我实施承诺的方式究竟出了什么问题 . 正确设置reducer和redux操作(我知道因为我已经从redux动作文件将获取的项目记录到控制台),我如何正确填充mapStateToProps中的prop值 . 目前的错误是:

enter image description here

我使用React 16.4.0

1 回答

  • 1

    一个简单的redux用例如下所示

    possibleMatches.jsx(组件文件)

    class PossibleMatches extends React.Component {
      state = {
        isFetching: false
      }
    
      componentDidMount() {
        this.setState({isFetching: true})
        fetchingSomethingFromServer()
        .then(resp => {
          this.setState({isFetching: false})
          this.props.UpdateRedux(resp)
        });
      }
    
      render() {
        const { isFetching } = this.state;
        const { data } = this.props;
        return (
          isFetching ? <div>loading...</div> : <div>{data}</div>
        )
      }
    }
    
    export default connect(state => ({ data: state.possibleMatches.data }), {UpdateRedux})
    

    actions.js(action creator file)使用此操作将任何数据更新为redux

    export const UpdateRedux = (data) => {type: 'UPDATE_REDUX', payload: data}
    

    reducers.js这是保存redux状态的文件

    const defaultState = {
     data: null
    }
    
    export default (state = defaultState, action) => {
      switch(action.type) {
        case 'UPDATE_REDUX':
          return {data: action.payload};
        default:
          return state
      }
    }
    

    在您的组合减速器中导入此减速器并按如下方式进行分配

    import possibleMatches from 'reducers.js';
    
    combineReducers({ possibleMatches });
    

相关问题