I have one component, it contains two other components. First "NotifyMessage" component is rendered for the whole page. Second "NotifyMessage" component is rendered just only inside pop up. Both components subscribe to the redux store and get appropriate message and type (success or error) from there. Currently, if something happens - "NotifyMessage" component rendered in both places (popup and whole page). What is the best approach to separate render logic? I'd like to render only one component in one place.
create a flag State , say "compAlreadyShown" with boolean value. Use it to conditionally show hide in popup.
I've added another message to my redux store for "pop'ups" cases and pass it to my common "NotifyMessage" component as a children. For now I've two sources of truth for messages in my store instead of one. May be there is a better solution but it fix my problem.
Related
[This is the Codesandbox with all of the code that exemplifies the issue I'm having. Sorry, SO doesn't allow for proper React code with TSX, etc.]
I have some tabs, naturally, whenever I click on each of them, my state changes (namely selectedTab) and the body that's being rendered. Each tab item has a body that goes with it, the first tab, in my case, has a component that, if you click, a count is increased. Well, whenever the tab changes, that count gets reset. In fact, it's a full-rerender all around.
The problem with doing a full re-render is that - not only is it inefficient, given how the user's gonna use it, but it also adds fuel to the fire: what if the user inputs something on a tab, then switches to another tab to do something else and then back to the original one? He's just lost what he typed in.
Naturally, this can be solved if we render all of the tabs' content upfront and we just play with display: none, and it'd be a good solution, but I'm also trying to learn.
I understand how React re-renders things and why this happens, but is there a way to fix it?
In my case, if you look at useTabs, the content variable simply looks at the corresponding tab's component key and takes outputs that. It's there that, I think, I need to memoize things.
Uhm, I guess you can't prevent calling your custom hook, this will lead to invariant violation error.
These hooks in the component will be executed on each render -> thus 'resets' your tabs.
You should rely on useEffect dependencies argument to run conditional code to see if values needs to be changed.
as long as your in the same app you could use contextApi,react context docs otherwise you can use localstorage, localstorage tutorial
or just create this state in the parent component and pass it down as props?
Very often I find myself in a scenario which is very common I think, when I need to render data in a child component that comes from props, but is fetched from an api in the parent component. On the first render the data is still fetching, so the child component has nothing to render. I sometimes use a loading flag, and render the whole child component when the data comes, else I render some message that the data is still loading or I render null. But what if I want the component to be there and only fill the data when it comes? This is very tedious if I have props that are nested objects, so I have to define the structure of the data in the state of the parent so I don't access objects that don't exist, or I have to check manually in the child component if they are not undefined. So, the question is, is there any recommended way of doing this? How do you do it?
One of the most popular practice is to render string: 'N/A' that mean not applicable, not available or no answer.
There are many ways in fact.
Most common way is to render something to indicate user that there is something loading in the background and you could wait to see that.
Could be simple text "We're loading your content....."
Could be something like spinning icon.
Or event better the facebook preloader.
I am new on react. I am working on react application with redux. I have a form (I am using redux-form) by which I can save data or edit data.
my problem is , In edit mode I populate data using componentWillReceiveProps. and populated perfectly, now when I try to clear any field on form its again fill.
componentWillReceiveProps(nextProps){
this.props.dispatch(initialize('NewProject', nextProps.project.project[0]));
}
I would be grateful for any help.
Is there a reason you're not dispatching this action somewhere else, like in componentDidMount? I can't say without seeing more code, but it's possible that whenever you edit your form, React again calls componentWillReceiveProps and overwrites whatever you did with the behavior you've given your component.
Per the React documentation:
Note that React may call this method even if the props have not changed, so make sure to compare the current and next values if you only want to handle changes. This may occur when the parent component causes your component to re-render.
It may be a good idea for you to move your dispatch to a more predictable event if possible, like componentDidMount. Typically, your render method should be capable of handling different cases if a component has multiple possible states. You could also create an edit and save version of your component, and render one or the other based on the props you receive. The best way to "populate" data, as you put it, is to define propTypes for your component, and then use your props to insert that data into elements in the render method.
I'm just wondering if there's anyway of completely cloning an already rendered React component. I've read about cloneElement but when I render that clone I get an error:
Uncaught error: Invariant Violation: Element type is invalid
I'm also wondering if this will clone the element's child elements, and their subsequent input values. For example, if some text is in one of the inputs, and then the component is cloned, will these values be preserved? Or is my only option to store those values before clone? This will make it very tightly coupled I feel.
As a general rule, we should always try to keep our components as stateless as possible, meaning that the data you input in the form should be stored somewhere outside of the component (a Store, maybe? ... I'm thinking about http://alt.js.org/docs/stores/).
With this approach, you'll have your component listening to that store. You can have as many copies of the component as you'd like, but the single source of truth would be your store.
Another scenario, if the same component should show data from different stores, then do not use stores, and use props. Have the parent component be the one listening to its store, and pass the necessary data to the child component (the one that you want to have clones in several places in your app).
I hope that helps,
I'd like to make a React component that, when inserted inside any other component, will display its state in a DIV floated to the right of the screen. Let name it StateExplorer.
Because many StateExplorers can be used on the same page, the DIVs will stack with the same z-index.
The challenge here is to make StateExplorer easily non-verbosely embeddable, like this:
<SomeComponent>
<StateExplorer/>
....
</SomeComponent>
The particular issue here is: how do I hook on componentWillUpdate() so that the StateExplorer always displays up-to-date state? I could use a mixin, but that throws 2 problems:
componentWillUpdate() can be implemented already in the parent component
adding a mixing adds more verbosity; the ideal case is to just add StateExplorer and nothing more.
P.S. I know about React Debug Tools, but it's not so convenient in some cases and adds extra steps before you can see state of a single component.
Sounds like what you need is a Higher-order component.
Here is a good article about it: https://medium.com/#dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750