簡體   English   中英

React(react-native)/ Redux-如何過濾來自Redux存儲的數據?

[英]React (react-native) / Redux - How to filter data coming from redux store?

我試圖完成以下任務:我想顯示數據,然后對其進行過濾/顯示過濾結果。 我是redux的新手,已經閱讀了很多書,我發現使用庫重新選擇非常普遍,但是由於我只需要在一個地方使用filter選項,所以我沒有這樣做。 我試圖實現我閱讀的內容,但是以某種方式無法真正起作用。 我也不確定最好的方法是在動作內部還是在mapStateToProps內部(我讀過(我讀到,數據應該在reducer內部進行突變,以防其他地方需要它,這就是為什么我試圖在mapStateToProps內部進行)) 。 如果有人看我的代碼並告訴我我做錯了,那就太好了! 謝謝!

我收到的錯誤是“即使“ state.allData.data”是對象數組,也無法讀取null的屬性過濾器,所以我不理解它。.我也不確定其余所有內容。

附言 抱歉,要讀取這么多代碼,但我嘗試刪除了不必要的部分

行動:

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)

我在這里假設您的化簡文件中的FECHTING_DATA是FETCHING_COIN_DATA。

發生了什么事,當您調用dispatch({type: FETCHING_DATA})時,reducer將數據設置為null ,更改了props並重新渲染了組件。 發生這種情況時,redux會調用mapStateToProps方法,此時allData.datanull ,從而給您帶來錯誤。 為了避免這種行為,您應該設置data: []

關於在哪里過濾數據。 mapStateToProps的問題是,只要該組件的props發生更改,就會調用該問題。 因此,如果您有一個更復雜的組件並映射了許多不同的道具,那么即使過濾器參數可能沒有更改,您也會多次重新過濾列表。 如果列表很大,可能會導致應用程序滯后。

我這樣做的方法是使用componentWillReceiveProps生命周期方法,並檢查過濾器是否已更改,並且它們將過濾后的列表存儲在狀態中。

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(() => { /* ... */ });
}

希望能有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM