简体   繁体   中英

React / Redux / Reselect - How to pass in argument, stored in local state to be used to filter data stored in redux store?

I am rendering data (having it in my redux store), I have a search bar and want to filter the data results based on the search input. I am using reselect library and cant seem to make it work. I read their documentation and Ive tried various things:

I store the search input in my local state and want to pass it in as an argument, however it only seems to work for props which I dont have (as Im saving input in state of comp.) Then I tried to call my selector function in my onChange function, passing in the input --> problem here is, Im receiving the input, but not the data.

Could someone help?

selector.js

import {createSelector} from 'reselect'

const dataSelector = (state, props) => {
    return state.data;
}

export const filterResults = (data, input) => {
    return createSelector(
        dataSelector,
        data => data.filter((item) => item.symbol.toLowerCase().includes(input) || item.name.toLowerCase().includes(input))
    )
}

Container:

class App extends React.Component {
constructor(props){
    super(props);
    this.state = {
        searchInput: ""
    }
}

filterData = (e)=> {
    const input = e:
    this.setState({
        searchInput:input
    })
}

render (){
    ...
    this.props.products.data.map((item, index) =>...
    ...
    <input
    onChange={this.filterData}
    />
 }

}

function mapStateToProps(state, props) {
    return {
        products: state.data,
        filteredData: filterResults(state,this.state.input)
    }
}

export default connect(mapStateToProps, { actioncreator })(App)

UPDATE:

I changed code and now store the input in my redux store. I call my actioncreator inside my onChange function which returns (only) the input, my (input)reducer is is also returned inside my mapstatetoprops function.

selector:

import {createSelector} from 'reselect'

const selectedData = state => state.data;
const input = state => state.searchFilter.searchInput;

const getData = (data, searchInput) => {
    return data.filter((item) => item.name.toLowerCase().includes(searchInput))
}

export default createSelector(
    selectedData,
    input,
    getData
)

In my container, I changed my mapStateToProps to:

import selectedData from ...

function mapStateToProps(state) {
    return {
        products: state.data,
        searchFilter: state.searchFilter,
        selected: selectedData(state)
    }
}

Problem:

  • Im getting the error: canno filter null - however I when I console log data inside my getData function- I DO get an array full of objects so its not null

  • Also I tested my action creator for the input and it works, however insight input function (in my selector file) its undefined - which should actually an empty string at first as thats the initial value in my reducer..

The reason your mapStateToProps isn't called on input, is because it's only called when the redux store is updated . I would suggest you store the search input state in the redux store to be able to rerun mapStateToProps and your selector on change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM