通过redux将数据从API加载到react native的listview中

4smxwvx5  于 2023-06-06  发布在  React
关注(0)|答案(2)|浏览(136)

我想创建一个简单的应用程序使用RN,这只是从API数据加载列表视图。其思想是:

  • 我从我的Action中获取API,然后将其传递给负载上的reducer
  • 在reducer上,我将数据传入我的组件
  • 在我的组件上,我对componentWillMount执行getData函数
  • 然后,在它加载后,我将使用此数据设置我的listView的dataSource

但问题是,数据不会加载。它是在调用componentWillMount时加载的,但是我不知道如何更新我的组件,或者如何检测在componentWillMount中的getData完成它的任务后创建的新 prop 。
这是我的代码片段

// 1) ProductCategoryAction.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) ProductCategoryReducer.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) ProductCategoryList.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);
acruukt9

acruukt91#

首先,你应该了解React组件的生命周期。
您试图从componentWillMount中的API获取数据,但当componentDidMount生命周期达到创建dataSource变量的位置时,数据仍在获取。所以你不会得到任何数据源。
删除componentDidMount函数,并像这样更改render函数,以便每当您获取product_categories时,都会生成dataSource。

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" />
    );
}
6ojccjat

6ojccjat2#

是否有必要在 prop 更新后调用componentWillReceiveProps

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

当你在那个时候更新数据时,你可以在nextprops中访问这些数据

相关问题