Connect Search Bar And Search Results Components To Global State
I am new to ReactJS and I recently came up with this redux date store that react uses mostly. I am trying to have a good grasp on it. Just for the understanding purpose, I have an
Solution 1:
1. You should change your store display function which always record to origin data
Maybe you can change this to see store change:
functiongetState() {
console.log(store.getState());
}
Just console.log(initialState.jsonData);
always show the origin data.
2. reducer
function always need to change the current state
functionreducer(state = initialState, action) {
console.log('reducer', state, action);
switch(action.type) {
case'SEARCH':
const updatedPattern = newRegExp(action.payload.pattern)
return {
jsonData: state.jsonData.filter(item => updatedPattern.test(item.state))
};
default:
return state;
}
}
The key change is after: jsonData: state.jsonData.filter(item => updatedPattern.test(item.state))
3. Maybe you can use store.subscribe(handleChange)
to get store change
const unsubscribe = store.subscribe(getState)
use the store.subscribe
to auto get state change action like react-redux
does.
Solution 2:
Since both OP's approach and accepted answer have several critical flaws let me share my suggestions:
- you don't want to replace source array within your current state with its filtered copy - if you typed
Mah
within your search bar and just one second later decided to search forelh
you may get an empty search results if your previously filtered array didn't contain matches (while original one did); - using RegExp
test()
for basic case-insensitive partial match is an absolute overkill, there's a much less expensive option, based onArray.prototype.includes()
together withArray.prototype.some()
if required (you may refer live-snippet on the bottom for example); - both earlier posted solutions suggest using
subscribe... store.dispatch()
pattern to access globally stored state variables, which is not recommended
If you really need to keep your search results stored within global state and you want to obtain those through dispatching corresponding action (e.g. SEARCH
) and accessing global searchResults
within arbitrary component connect()
method, combined with mapDispatchToProps()
and mapStateToProps()
, respectively, should be used.
You may find the live-demo below:
//dependenciesconst { render } = ReactDOM,
{ createStore } = Redux,
{ connect, Provider } = ReactRedux//search action, initial state, reducer, storeconstSEARCH = 'SEARCH',
initialState = {jsonData:[{"id":"1","country":"India","state":"Andhra_Pradesh","city":"Amaravati","station":"Secretariat, Amaravati - APPCB","last_update":"18-12-2019 09:00:00","pollutant_id":"PM2.5","pollutant_min":"62","pollutant_max":"278","pollutant_avg":"139","pollutant_unit":"NA"},{"id":"2","country":"India","state":"Andhra_Pradesh","city":"Amaravati","station":"Secretariat, Amaravati - APPCB","last_update":"18-12-2019 09:00:00","pollutant_id":"PM10","pollutant_min":"74","pollutant_max":"136","pollutant_avg":"104","pollutant_unit":"NA"},{"id":"149","country":"India","state":"Delhi","city":"Delhi","station":"Lodhi Road, Delhi - IMD","last_update":"18-12-2019 09:00:00","pollutant_id":"NO2","pollutant_min":"NA","pollutant_max":"NA","pollutant_avg":"NA","pollutant_unit":"NA"},{"id":"150","country":"India","state":"Delhi","city":"Delhi","station":"Lodhi Road, Delhi - IMD","last_update":"18-12-2019 09:00:00","pollutant_id":"CO","pollutant_min":"34","pollutant_max":"117","pollutant_avg":"57","pollutant_unit":"NA"}], searchResult:[]},
appReducer = (state=initialState, action) => {
switch(action.type){
caseSEARCH : {
const {jsonData} = state,
{searchedString} = action,
searchResult = searchedString.length ?
jsonData.filter(item =>Object.values(item).some(val =>
val
.toLowerCase()
.includes(searchedString.toLowerCase()))) :
[]
return {...state, searchResult}
}
default: return state
}
},
store = createStore(appReducer)
//searchbar ui componentconstSearchBar = ({searchResults}) => (
<inputonKeyUp={e => searchResults(e.target.value)} />
)
//connect searchbar component's searchResult prop to dispatching SEARCH actionconstmapDispatchToProps = dispatch => ({
searchResults: val =>dispatch({type: SEARCH, searchedString: val})
}),
SearchBarContainer = connect(null, mapDispatchToProps)(SearchBar)
//search results ui componentconstSearchResults = ({results}) => (
<div>
{results.map(item => <div>{JSON.stringify(item)}</div>)}
</div>
)
//connect global state searchResult to component's resultsconstmapStateToProps = ({searchResult:results}) => ({results}),
SearchResultsContainer = connect(mapStateToProps)(SearchResults)
//global Povider wrapper
render (
<Provider {...{store}}><SearchBarContainer /><SearchResultsContainer /></Provider>,
document.getElementById('root')
)
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.3/react-redux.min.js"></script><divid="root"></div>
Post a Comment for "Connect Search Bar And Search Results Components To Global State"