I have a simple component that uses Redux and Redux Sagas. The action is dispatched when a button is clicked and it changes the state value asynchronously.
I am creating a storybook component for this and I have already set up a decorator that uses the Provider(the store has been configured).
The storybook component gets the desired state value, however, it fails to dispatch the action.
I am unable to figure out what is the reason behind this. I am new to Storybook, any idea why the action is not dispatching?
Related
I am able to change state of App from webcomponent and get initial state using recoil-nexus package. But unable to get changing state. For eg- changed state after state is mutated in webcomponent or in app.
As RecoilRoot internally uses react's context API and Webcomponent (shadowDOM) creates new React tree which do not have access to context of the RecoilRoot. How to get changing state in webcomponent of the atom in App?
Webcomponent reference - https://reactjs.org/docs/web-components.html,
Failed attempts:
Tried creating custom hook to get recoil state after useRecoilSnapshot changes.
Tried Hook rerun on reference of nexus.get change.
Tried attaching custom state to window using useRecoilTransactionObserver_UNSTABLE(callback).
Tried recoil-outside which uses rxjs to observe state.
Tried recoil-sync but did not received event in 'write' event handler prop in webcomponent. It only works inside RecoilRoot and not outside.
getRecoilPromise might work but how to use async at top level of the component? Tried in useEffect but it did not work for me.
Nothing seems to refresh state in webcomponent.
Alternate Queries:
How to sync snapshot between two different RecoilRoot (which are not nested)?
React component tree in dev tool -
Preface:
This is an authentication mechanism in my project.
I am refactoring from using Contexts to Redux to control state
The Redux store holds a "isLogged" as a boolean as a part of the state. Upon successful login (the user submits the form with the correct email and password), an axios response validates the user and the client dispatches an action with a state change. The state change happens successfully, based on what I see using the redux dev tools extension.
The Problem:
I have a navbar component that conditionally renders links public and private components based on the isLogged state. It just doesn't rerender when the store state is updated, so currently the user is not able to see an updated navbar, even though the state change happens as it should.
Thank you in advance for your help.
I just solved the problem.
I had to access the store state via the useSelector hook from "react-redux". It seems that when I was trying to just grab the state earlier using the store.getState() method and storing it in a variable and passed down through props, the function components were not listening to the updates.
Let's say I have a music component connected to the "play" prop in the redux store.
When "play" is updated, I would like to update the playback status (play, pause, etc) accordingly. However, this does not influence how the component looks. So I'm wondering where to perform the update actions?
I was using componentWillReceiveProps to control the playback when the prop is updated, it works but apparently that is incorrect use according to the React team, and the method will be deprecated.
You need to dispatch an action with the selected playback status within the onClick function that is passed through a reducer and updates the state of the store. The component, if connected properly to the store using the connect function in the react-redux library, will automatically update the rendering of the component.
I am very confused recently.
When I write redux, if I have to call api ,I will put an action to update reducer, the component just render the data from props
But recently I see my coworker just call api in container component and then update the component state.
He says if your data do not need to share with other component, you can call api in component, so you don't have to write so many code in actions and reducers.
I thought this is very convenient. For example: If I have a feature : When user click the button, I have to send an email.
This feature do not need to update store by reducer, just have to alert "send success"
So I can write this code in container component:
async onClick() {
// 1. call api
const {error, response} = await sendMail({email: this.state.email});
if (response){
// 2. alert success
this.setState({
modal: {
show: true,
}
});
}
}
But I don't know if this match redux's principle.
Can I call api directly in component if the state do not need to share with other component??
You can call api from dispatched actions or from React components: it is your choice to make. There is no mandatory rules here and it depends on what you want to do with your components:
When to use React states:
It is better to have smart component handling their own state because it ease the integration in external projects. Having a component that uses Redux means a project needs to add the requires reducers to use the component.
If a component handles information not required by any other components, use React state. It is often the case for information related to UI state.
When using Redux reduces:
If you need to test your component, prefer Redux because you'll be able to connect "test actions" to your component when testing them.
If you need to share a bundle of data through components, prefer Redux to mutualise information.
This question has been treated by Gaeron on Redux github repository if you want to have a look. He explains:
Use React for ephemeral state that doesn't matter to the app globally and doesn't mutate in complex ways. For example, a toggle in some UI element, a form input state. Use Redux for state that matters globally or is mutated in complex ways. For example, cached users, or a post draft. Sometimes you'll want to move from Redux state to React state (when storing something in Redux gets awkward) or the other way around (when more components need to have access to some state that used to be local). The rule of thumb is: do whatever is less awkward.
I suggest you have a look at classux
I have a react native project and I am using redux actions and reducers to handle my store.
I have a smart connected component and I call my actions through dispatch in componentWillMount() and then I have mapStateToProps and I map the data I get from my store to props.
Problem is the only way to check if the props are changed, is by putting it inside render function. In my case I want to navigate to another page if I get props filled with some data. It all works fine but I get warning from React that its anti pattern. Is there any other way of doing this? Am I doing it right?
You should implement the method componentWillReceiveProps instead of comparing the values in the render
Another (preferable) approach would be the action responsible to update the values, do the navigation (or dispatch another actions that would do the navigation stuff). Check redux-thunk