2017-02-02 7 views
1

私はreact-redux、redux-persist、およびredux-thunkで反応するネイティブアプリを持っています。React Native with Redux:データが読み込まれ、空が表示されます。

コンポーネントでは、データの長さが1より小さい場合は、エラーが表示され、データは表示されません。

「データがありません」と表示されていますが、実際にはデータは小道具にあります。コンソールログをチェックすると、(redux-loggerを使用して)データが小道具で利用可能になります。

forceUpdate()componentDidMountに置いても役に立たない場合もあります。

しかし、もし私がforceUpdate()をタイムアウトにすると、データが読み込まれます。

setTimeout(()=>{ 
     this.forceUpdate(); 
    }, 1000); 

何が問題なのですか?データが小道具から読み込まれる前にレンダリングが行われますか? CoursesPage.js

import {bindActionCreators} from "redux"; 
 
import {connect} from "react-redux"; 
 
import Courses from "./components/Courses"; 
 
import {Actions as routes} from "react-native-router-flux"; 
 
import * as courseActions from "./courses.actions"; 
 

 
function mapStateToProps(state) { 
 
\t return { 
 
\t \t user: state.auth.user, 
 
\t \t users: state.auth.users, 
 
\t \t courses: state.courses.courses, 
 
\t \t lectures: state.courses.lectures, 
 
\t \t courseDetails: routes.courseDetails, 
 
\t \t openProfile: routes.profilePage 
 
\t } 
 
} 
 

 
function dispatchToProps(dispatch) { 
 
\t return bindActionCreators({ 
 
\t \t getCourses: courseActions.getCourses 
 
\t }, dispatch); 
 
} 
 

 
export default connect(mapStateToProps, dispatchToProps)(Courses);

Courses.js

import React, {Component, PropTypes} from "react"; 
 
import { 
 
    ActivityIndicator, 
 
    ListView, 
 
    StyleSheet, 
 
    Text, 
 
    View, 
 
    Image, 
 
    NetInfo, 
 
    Alert, 
 
    TouchableOpacity, 
 
    ScrollView, 
 
    Dimensions, 
 
    Platform, 
 
    RefreshControl 
 
} from 'react-native'; 
 
import { Loader, Accordion, I18n, CustomNavBar, CustomAccordion } from "../../common/components"; 
 
import styles from "../../common/styles"; 
 
let DeviceInfo = require('react-native-device-info'); 
 
import Icon from 'react-native-vector-icons/Ionicons'; 
 
let { width, height } = Dimensions.get('window'); 
 

 
export default class Courses extends Component { 
 
\t static propTypes = { 
 
\t \t user: PropTypes.string.isRequired, 
 
    users: PropTypes.object.isRequired, 
 
\t \t courseDetails: PropTypes.func.isRequired, 
 
\t \t courses: PropTypes.object.isRequired, 
 
    getCourses: PropTypes.func.isRequired, 
 
    openProfile: PropTypes.func.isRequired 
 
\t }; 
 

 
\t constructor(props) { 
 
    super(props); 
 
    this.state = { 
 
     isLoading: false, 
 
     isRefreshing: false 
 
    }; 
 
    this._isMounted = false; 
 
    } 
 

 
\t componentWillMount(){ 
 
    this._isMounted = true; 
 
    const { users, getCourses } = this.props; 
 
    getCourses(users); 
 
\t } 
 

 
    componentWillUnmount(){ 
 
    this._isMounted = false; 
 
    } 
 

 
    componentWillReceiveProps(){ 
 
    setTimeout(()=>{ 
 
     this.forceUpdate(); 
 
    }, 1000); 
 
    } 
 

 
    componentDidMount(){ 
 
    setTimeout(()=>{ 
 
     this.forceUpdate(); 
 
    }, 1000); 
 
    setTimeout(()=>{ 
 
     this.forceUpdate(); 
 
    }, 2000); 
 
    } 
 

 
    async loadData(){ 
 
    await this.props.getCourses(this.props.users); 
 
    setTimeout(()=>{ 
 
     this.forceUpdate(); 
 
    }, 1000); 
 
    } 
 

 
    selectRow(courseData) { 
 
    this.props.courseDetails({ 
 
     courseData: courseData 
 
    }); 
 
    } 
 

 
    renderData(containerList){ 
 

 
    /* rendering .... */ 
 
    
 
    } 
 

 
\t render() { 
 
    const {user, users, getCourses, courses, openProfile} = this.props; 
 
    const data = courses[user]; 
 
    let containerList = []; 
 
    Object.keys(data).forEach((d)=>{ 
 
     let courseList = []; 
 
     Object.keys(data[d].courses).forEach((c)=>{ 
 
     courseList.push(data[d].courses[c]); 
 
     }); 
 
     containerList.push({ 
 
     id: data[d].id, 
 
     title: data[d].title, 
 
     courses: courseList 
 
     }); 
 
    }); 
 

 
    return (
 
     <View style={styles.container}> 
 
      <View style={{ width: width, height: Platform.OS == "ios" ? 64 : 54}}> 
 
      <CustomNavBar 
 
       width={width} 
 
       height={Platform.OS == "ios" ? 64 : 54} 
 
       title={I18n.t("details_page_book_button")} 
 
       titleSize={18} 
 
       buttonSize={15} 
 
       background={"#00a2dd"} 
 
       color={"#FFF"} 
 
       rightIcon={"ios-person-outline"} 
 
       rightIconSize={30} 
 
       rightAction={()=> { openProfile(); }} 
 
      /> 
 
      </View> 
 
      <View style={{ height: Platform.OS == "ios" ? height - 114 : height - 130 }}> 
 
      {!this.state.isLoading ? 
 
       <ScrollView 
 
       refreshControl={ 
 
       <RefreshControl 
 
        refreshing={this.state.isRefreshing} 
 
        onRefresh={this.loadData.bind(this)} 
 
        tintColor="#00a2dd" 
 
        title="" 
 
        titleColor="#00a2dd" 
 
        colors={['#00a2dd', '#00a2dd', '#00a2dd']} 
 
        progressBackgroundColor="#FFFFFF" 
 
       /> 
 
       } 
 
      > 
 
       {this.renderData(containerList)} 
 
      </ScrollView> 
 
      :<ActivityIndicator 
 
     \t \t \t \t animating={true} 
 
     \t \t \t \t style={{ paddingTop: Platform.OS == "ios" ? (height - 114)/2 : (height - 130)/2 }} 
 
     \t \t \t \t color={'#00a2dd'} 
 
     \t \t \t \t size={'small'} 
 
     \t \t \t />} 
 
      </View> 
 
     </View> 
 
    ); 
 
\t } 
 
}

enter image description here

+0

あなたが '' COMPONでprops'にアクセスすることができますentWillMount'ライフサイクルメソッド?私は 'redux'からの小道具の価値は何ですか? –

+0

@Yaseminçidemコンポーネントがマウントされるときに私は小道具にアクセスできますが、すべてのデータがそこにあるわけではありません。質問のスクリーンショットをご覧ください。私は質問を更新しました。 – Ataomega

+0

あなたの目標はここにあります 'const {users、getCourses} = this.props;' 'getCourses(users);' はあなたのアクションメソッド 'getCourses'ですか?アクションにアクセスするための.porps.actions.getCourses' –

答えて

1

私はあなたがそれは同じdata.So I見られているような状態を変更いけないと思いますコードを変更する必要があることを示唆次のようにしてください。また、あなたは状態を変更するために不変のjsを設定する必要があります。

courseActions

export function getCoursesRequest() { 
    return { 
    type: "GET_COURSES_REQUEST" 
    } 
} 
export function getCoursesSuccess (json) { 
    return { 
    type: "GET_COURSES_SUCCESS", 
    payload: json 
    } 
} 
export function getCoursesFailure (json) { 
    return { 
    type: "GET_COURSES_FAILURE", 
    payload: json 
    } 
} 
export function getCourses (sessionToken) { 
    return dispatch => { 
    dispatch(getCoursesRequest()) 
    // store or get a sessionToken 
    return appAuthToken.getSessionToken(sessionToken) 
     .then((token) => { 
     return BackendFactory(token).getCourses() 
     }) 
     .then((json) => { 
     dispatch(getCoursesSuccess(json)) 
     }) 
     .catch((error) => { 
     dispatch(getCoursesFailure(error)) 
     }) 
    } 
} 

coursesInitialState

const {Record} = require("immutable"); 

var InitialState = Record({ 
    courses: {} 
}); 
export default InitialState; 

減速

const InitialState = require("./authInitialState").default;  

const initialState = new InitialState(); 

export const courseReducer = (state = initialState, action) => { 
    if (!(state instanceof InitialState)) return initialState.mergeDeep(state); 
    switch (action.type) { 

     case "GET_COURSES_SUCCESS": 
      const {value} = action.payload; 
      let nextState = state.setIn(["courses"], value; 

      return nextState; 
     case "GET_COURSES_FAILURE": 
    } 
} 
+0

あなたの答えをありがとう。私はそれを試してみます。 – Ataomega

関連する問題