代码之家  ›  专栏  ›  技术社区  ›  baycisk

通过Redux将数据从API加载到React Native的ListView中

  •  0
  • baycisk  · 技术社区  · 6 年前

    我想用RN创建一个简单的应用程序,它只是从API数据加载ListView。 其理念是:

    • 我从我的操作中获取API,然后将其传递给有效负载上的Reducer。
    • 在Reducer上,我将数据传递到组件中
    • 在我的组件上,我在componentwillmount上执行getdata函数
    • 然后,加载后,我将使用此数据设置ListView的数据源

    但问题是,数据无法加载。它是在调用componentwillmount时加载的,但是我不知道如何更新我的组件,或者如何检测在componentwillmount中的getdata完成它的任务后创建的新属性。

    这是我的代码段 1)产品类别.js

    export const getProductCategory = () => {
        return (dispatch) => {
            dispatch({ type: GET_PRODUCT_CATEGORY });
    
        fetch(CONFIG_GET_PRODUCT_CATEGORY_API)
            .then((response) => response.json())
            .then((responseJson) => getProductCategorySuccess(dispatch, responseJson.result))
            //.then((responseJson) => console.log(responseJson.result))
            .catch(() => getProductCategoryFail(dispatch));
    }
    };
    
    
    
    const getProductCategorySuccess = (dispatch, product_categories) => {
        dispatch({
            type: GET_PRODUCT_CATEGORY_SUCCESS,
            payload: product_categories
        });
    };
    const getProductCategoryFail = (dispatch) => {
        dispatch({ 
            type: GET_PRODUCT_CATEGORY_FAIL
        });
    };
    

    2)产品类别reducer.js

    export default (state=INITIAL_STATE, action) => {
    
    console.log(action);
    
    switch(action.type) {
        case GET_PRODUCT_CATEGORY:  
            return { ...state, loading: true, error:'' };
        case GET_PRODUCT_CATEGORY_SUCCESS:  
            return { ...state, ...INITIAL_STATE, product_categories: action.payload };
        case GET_PRODUCT_CATEGORY_FAIL:  
            return { ...state, error: 'Couldn\'t load category data.', loading: false };
        default: 
            return state;
    }
    };
    

    3)产品类别列表.js

    class ProductCategoryList extends Component {
        componentWillMount() {
            this.props.getProductCategory();
    
    
        const ds = new ListView.DataSource({
            rowHasChanged: (r1, r2) => r1 !== r2
        });
    
        this.dataSource = ds.cloneWithRows(this.props.product_categories);
    }
    
    componentDidMount() {
    
        console.log(this.props);
    
        const ds = new ListView.DataSource({
            rowHasChanged: (r1, r2) => r1 !== r2
        });
    
        this.dataSource = ds.cloneWithRows(this.props.product_categories);
    
    }
    
    renderRow(product_category) {
        return <ProductCategoryListItem item={product_category} />
    }
    
    render() {
        if(this.props.loading) {
            return (
                <Spinner size="small" />
            );
        }
        if(this.props.error) {
            return (
                <View style={styles.errorWrapperStyle}>
                    <Text style={styles.errorTextStyle}>{this.props.error}</Text>
                </View>
            );
        }
        return (
            <ListView
                dataSource={ this.dataSource }
                renderRow={ this.renderRow }
                enableEmptySections={ true }
            />
        );
    }
    }
    
    const styles = StyleSheet.create({
        errorTextStyle: {
            fontSize: 14,
            alignSelf: 'center',
            color: 'red'
        },
        errorWrapperStyle: {
            backgroundColor: '#999999',
            padding: 2
        }
    });
    
    const mapStateToProps = ({ productCategories }) => {    
        const { product_categories, error, loading } = productCategories;
        return { product_categories, error, loading }
    }
    
    export default connect(mapStateToProps, { getProductCategory })(ProductCategoryList);
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Lasitha    6 年前

    首先你应该了解 React Component life cycle .

    您正在尝试从中的API获取数据 componentWillMount ,但当 componentDidMount 在创建数据源变量的地方,生命周期已经满足。所以你没有任何数据源。

    删除您的 组件安装 函数并像这样更改渲染函数,以便每当 product_categories 将生成数据源。

    render() {
        let {loading, error, product_categories} = this.props;
    
        if(error) {
            return (
                <View style={styles.errorWrapperStyle}>
                    <Text style={styles.errorTextStyle}>{error}</Text>
                </View>
            );
        }
    
        if(product_categories & !loading){
            const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    
            this.dataSource = ds.cloneWithRows(product_categories);
    
            return (
               <ListView
                   dataSource={ this.dataSource }
                   renderRow={ this.renderRow }
                   enableEmptySections={ true }
               />
            );
        }
        return (
            <Spinner size="small" />
        );
    }
    
        2
  •  0
  •   HpDev    6 年前

    是否需要在更新props后调用componentwillreceiveprops

    componentWillReceiveProps(nextProps){
     this.loadPosts(nextProps)**HERE YOU CAN GET UPDATED PROPS**
    },
    

    当您在那时更新数据时,您可以在nextrops中访问这些数据。