Reputation: 409
I have a react native functional component and I am using
store.subscribe --> store.getState().id
to reach out to my redux store to retrieve the "id" stored in my redux store.
When I console.log the id value after fetching it from the redux store I am not returning any data.
Am I reaching out to the store correctly in my useEffect function in my component?
Function Component AddTask.js
function AddTask () {
const [id, setId] = useState('');
useEffect(() => {
store.subscribe(() => {
setId(store.getState().id)
console.log(store.getState().id);
});
});
return (
...
);
}
Redux Store Reducer
(id will not be an empty string it is set to a value before fetching the data)
const initialState = { id: ''}
const counterReducer = (state = initialState,
action) => {
if (action.type === 'id') {
console.log('Store'+ action.payload);
return {
id: action.payload,
};
}
return state;
};
const store = createStore(counterReducer);
export default store;
Upvotes: 1
Views: 377
Reputation: 39290
The hooks useSelector
and useDispatch
are part of react-redux as well as the old way to connect to redux store with connect
.
You are using store directly in your component, this is not advisable since you now tightly coupled every component to a specific store implementation but regardless of a bad design decision the code should still work but you forgot to unsubscribe in the effect cleanup function and provided no dependencies so it runs every render. You probably are not doing something in code you didn't add to the question like what is dispatching the action and what do the redux devtools tell you?
Here is your code working:
const { createStore, applyMiddleware, compose } = Redux;
const initialState = {
id: 'initial id',
};
//action types
//using constants instead of strings for action type
const ID = 'ID';
//action creators
const setIdAction = (id) => ({ type: ID, payload: id });
const reducer = (state, action) => {
if (action.type === ID) {
return {
id: action.payload,
};
}
return state;
};
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
initialState,
composeEnhancers(
applyMiddleware(
() => (next) => (action) => next(action)
)
)
);
function App() {
//you did not set initial value correctly and assuming it
// was an empty string
const [id, setId] = React.useState(store.getState().id);
React.useEffect(() => {
store.subscribe(() => {
setId(store.getState().id);
});
}, []);
return (
<div>
id is: {id}
<button
onClick={() =>
store.dispatch(setIdAction('From button'))
}
>
set id
</button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<div id="root"></div>
When your code is not working I would advice you provide a minimal working example demonstrating the problem either by sandbox or snippet
The following is how you would use react-redux to connect the components to redux:
//Adding react-redux dependencies
const { Provider, useSelector, useDispatch } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;
const initialState = {
id: 'initial id',
};
//action types
//using constants instead of strings for action type
const ID = 'ID';
//action creators
const setIdAction = (id) => ({ type: ID, payload: id });
const reducer = (state, action) => {
if (action.type === ID) {
return {
id: action.payload,
};
}
return state;
};
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
initialState,
composeEnhancers(
applyMiddleware(
() => (next) => (action) => next(action)
)
)
);
function App() {
//no local state or effect needed
const id = useSelector((state) => state.id);
const dispatch = useDispatch();
return (
<div>
id is: {id}
<button
onClick={() =>
//no dependencies on store
dispatch(setIdAction('From button'))
}
>
set id
</button>
</div>
);
}
ReactDOM.render(
//add react-redux provider
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/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.2.0/react-redux.min.js"></script>
<div id="root"></div>
Upvotes: 1