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 Array of Objects stored in the store in a static manner for now.
like this:
const 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"
},
]
I am trying to create an action like this:
{
type: "SEARCH",
payload: {
pattern: 'Mah'
}
}
and I am dispatching this action. and trying to filter the store based on the pattern. I am taking a pattern and converting it as a RegExp. and using the test function to filter the data.
But somehow, It's not working the data is not getting filtered using RegExp. I am getting the same state even after filtering the data. I am not able to understand whats the problem is:
Here is the full code:
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import App from './App';
import './index.css';
const 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"
},
]
};
function reducer(state = initialState, action) {
console.log('reducer', state, action);
switch(action.type) {
case 'SEARCH':
const updatedPattern = new RegExp(action.payload.pattern)
return {
jsonData: initialState.jsonData.filter(item => updatedPattern.test(item.state))
};
default:
return state;
}
}
function getState() {
console.log(initialState.jsonData);
}
const store = createStore(reducer);
store.dispatch(
{
type: "SEARCH",
payload: {
pattern: 'And'
}
}
);
getState();
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
,
document.getElementById('root')
);
Since both OP's approach and accepted answer have several critical flaws let me share my suggestions:
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);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);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 globalsearchResults
within arbitrary componentconnect()
method, combined withmapDispatchToProps()
andmapStateToProps()
, respectively, should be used.You may find the live-demo below:
1. You should change your store display function which always record to origin data
Maybe you can change this to see store change:
Just
console.log(initialState.jsonData);
always show the origin data.2.
reducer
function always need to change the current stateThe key change is after:
jsonData: state.jsonData.filter(item => updatedPattern.test(item.state))
3. Maybe you can use
store.subscribe(handleChange)
to get store changeuse the
store.subscribe
to auto get state change action likereact-redux
does.