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,
Maybe you can change this to see store change:
function getState() {
console.log(store.getState());
}
Just console.log(initialState.jsonData);
always show the origin data.
reducer
function always need to change the current statefunction reducer(state = initialState, action) {
console.log('reducer', state, action);
switch(action.type) {
case 'SEARCH':
const updatedPattern = new RegExp(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))
store.subscribe(handleChange)
to get store changeconst unsubscribe = store.subscribe(getState)
use the store.subscribe
to auto get state change action like react-redux
does.
Mah
within your search bar and just one second later decided to search for elh
you may get an empty search results if your previously filtered array didn't contain matches (while original one did);test()
for basic case-insensitive partial match is an absolute overkill, there's a much less expensive option, based on Array.prototype.includes() together with Array.prototype.some() if required (you may refer live-snippet on the bottom for example);subscribe... store.dispatch()
pattern to access globally stored state variables, which is not recommendedIf 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:
//dependencies
const { render } = ReactDOM,
{ createStore } = Redux,
{ connect, Provider } = ReactRedux
//search action, initial state, reducer, store
const SEARCH = '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){
case SEARCH : {
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 component
const SearchBar = ({searchResults}) => (
<input onKeyUp={e => searchResults(e.target.value)} />
)
//connect searchbar component's searchResult prop to dispatching SEARCH action
const mapDispatchToProps = dispatch => ({
searchResults: val => dispatch({type: SEARCH, searchedString: val})
}),
SearchBarContainer = connect(null, mapDispatchToProps)(SearchBar)
//search results ui component
const SearchResults = ({results}) => (
<div>
{results.map(item => <div>{JSON.stringify(item)}</div>)}
</div>
)
//connect global state searchResult to component's results
const mapStateToProps = ({searchResult:results}) => ({results}),
SearchResultsContainer = connect(mapStateToProps)(SearchResults)
//global Povider wrapper
render (
<Provider {...{store}}>
<SearchBarContainer />
<SearchResultsContainer />
</Provider>,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.3/react-redux.min.js"></script><div id="root"></div>