React(react-native)/ Redux - 如何过滤来自redux商店的数据?

时间:2018-04-14 19:35:08

标签: javascript reactjs react-native redux

我试图完成以下操作:我想显示数据,然后过滤/显示过滤结果。 我是redux的新手并且已经阅读了很多,我看到使用库重新选择很常见,但由于我只需要在一个地方使用过滤器选项,我没有这样做。我试图实现我读到的内容,但不知何故它并没有真正起作用。另外我不确定这样做的最好方法是内部动作还是内部mapStateToProps就像我一样(我读到数据不应该在reducer中变异,以防在其他地方需要它,这就是为什么我试图在mapStateToProps中做到这一点) 。如果有人看看我的代码并告诉我我做错了什么,那就太好了!谢谢!

我得到的错误是'无法读取null的属性过滤器,即使" state.allData.data"是一个对象的数组,所以我不理解它。所以我完全不确定其余的。

聚苯乙烯。很抱歉要阅读这么多代码,但我试图删除不必要的部分

行动:

import axios from "axios";
import {FETCHING_DATA, FETCH_DATA_SUCESS, FETCH__DATA_ERR, FILTER__DATA} from "...";

export const FetchData = () => {
        return dispatch => {
            dispatch({type: FETCHING_DATA})

            return axios.get("https://example.com")
                .then(res => {
                    dispatch({type: FETCH_DATA_SUCESS, payload: res.data})
                })
                .catch(err => {
                    dispatch({type: FETCH_DATA_ERR, payload: err.data})
                })
        }
    },
    receiveSearchInput = (input) => {
        return dispatch => {
            dispatch({type: FILTER_DATA, input: input})
        }
    }

减速机:

import {FETCHING_DATA, FETCH_DATA_SUCESS, FETCH_DATA_ERR, FILTER_DATA} from "...";

const initialState = {
    isFetching: null,
    data: [],
    hasError: false,
    errorMsg: null,
    seachInput: ""
}

export default function (state = initialState, action) {
    switch (action.type) {
        case FETCHING_DATA:
            return {
                ...state, isFetching: true, data: null, hasError: false, errorMsg: null
            }
        case FETCH_DATA_SUCESS:
            return {
                ...state, isFetching: false, data: action.payload, hasError: false, errorMsg: null
            }
        case FETCH_DATA_ERR:
            return {
                ...state, isFetching: false, data: action.payload, haserror: true, errorMsg: action.err
            }
        case FILTER_DATA:
            return {
                ...state,
                seachInput: action.input
            }
        default:
            return state;
    }
}

index.js for reducer:

const rootReducer = combineReducers({
    allData: DataReducer
});

Container:

import React from "react";
import {connect} from "react-redux";
import {FetchCoinData, receiveSearchInput} from "..";
import { SearchBar } from 'react-native-elements'


class ItemContainer extends React.Component {
    componentDidMount() {
        this.props.FetchData()
    }

    filterData = (e) => {
        this.props.receiveSearchInput(e)
    }

    renderItems() {
        return this.props.allData.data.map((item, index) =>
            <Item
                key={index}
                name={item.name}
                symbol={item.symbol}
                price={item.price}
            />
        )        
    }
    render () {
        if (this.props.allData.isFetching) {
            return (
                <View>
                     ...
                </View>
            )
        }
        return (
            <View>
                <SearchBar
                    onChangeText={this.filterData}
                />
                    {this.renderItems()}
            </View>
        )
    }    
}

function mapStateToProps(state) {
    return {
        allData: state.allData,
        filteredItems: state.allData.data.filter((item) => item.symbol.toLowerCase().includes(state.allData.seachInput) || item.name.toLowerCase().includes(state.allData.seachInput))
    }
}

export default connect(mapStateToProps, { FetchData, receiveSearchInput })(ItemContainer)

1 个答案:

答案 0 :(得分:0)

我假设你的Reducer文件中的FECHTING_DATA是FETCHING_COIN_DATA。

当您调用dispatch({type: FETCHING_DATA})时,减少器会将数据设置为null,更改道具并重新渲染组件。发生这种情况时,redux会调用mapStateToProps方法,allData.datanull data: [],从而产生错误。要避免此行为,您应该设置componentWillReceiveProps

关于过滤数据的位置。 mapStateToProps的问题是,只要该组件的道具发生变化,就会调用它。因此,如果您有一个更复杂的组件,并且映射了许多不同的道具,那么即使过滤器参数可能没有更改,您也会多次重新过滤列表。如果它是一个很大的列表,这可能会导致您的申请滞后。

我这样做的方法是使用componentWIllMount(nextProps) { if(this.props.allData.searchInput != nextProps.allData.searchInput || // check if input has changed this.props.allData.data != nextProps.allData.data) { // check if data has changed // filter your data // ... this.setState({ filteredData }) } // And change your renderItems method to renderItems() { return this.state.filteredData.map(() => { /* ... */ }); } 生命周期方法并检查过滤器是否已更改,并将过滤后的列表存储在状态中。

v8::Isolate::AddMessageListenerWithErrorLevel

希望有所帮助!