I want to implement an idea using react-tabs where I change the content displayed in the TabPanels depending on a particular state.
I have tried to implement this by having a parent component (AppTabs) that depending on the value of the state (let's call it mode) it renders one of two different components: Tables or Graphs.
These two components return the TabPanels with the content that each of them should render.
Here is the code:
AppTabs:
AppTabs code
Tables:
Tables code
Graphs:
Graphs code
When I try to execute this, I get the following error message:
Warning: Failed prop type: There should be an equal number of 'Tab'
and 'TabPanel' in Tabs. Received 2 'Tab' and 0 'TabPanel'.
Does this mean that I need to declare all of the pieces of react-tabs (Tab, Tabs, TabList, TabPanel) in the same component or else it won't work? Or am I doing something wrong?
I want to do it this way because then I could have all of the states regarding the Tables component or the Graphs component separated. Otherwise, I would need to set all of the states for both of these components in AppTabs and I think that would be very cluttered and a nightmare to maintain.
Thank you for your feedback in advance! Have a great day!
I have an answer for this issue.
I asked the react-tabs team about this issue as well and this was their answer:
Hi. Unfortunately there is no way to declare your TabPanels in a separate component; the Tabs component can't detect them through the component boundary.
The team provided some suggestions on how to deal with this situation. They are explained in the discussion we had over at their github page.
Here is a link to the issue if anyone is interested in it: https://github.com/reactjs/react-tabs/issues/481
I hope this can be useful to someone else,
have a great day!
Related
I am developing a website in React.
In this website I have a screen - lets call it "book-an-appointment"
And I have multiple flows:
book an appointment for existing client
book an appointment for non-existing client
book-an-appointment is part of flow 1 and 2, with slight differences:
some buttons that are shown only in one of them
"next" button that takes the user to a different screen
it affects differently on the funnels
of course each one of them is in a different URL
and more...
Question: Which approach is best practice in developing such screen in react?
options I thought about are:
Creating A single screen that shows the relevant buttons and actions according to the state
Duplicating the screen for each flow (because of the small differences in it)
I am quite new to react. tried to look for an answer here and in google but couldnt find my answer.
In that case I would just use one Parent component with ether two child components with the different flows. You can make one JSON object where conditionally you add specific keys and you can later check if the isExisting field exists for example what kind of booking it is and show a the existing user flow component.
You could do it like that or have one component that just conditionally hides fields depending on what type of booking it is. In this case you would use conditional rendering. See the article below for more info.
https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator
I need a component that will look like this and depending on state something should change. (The point is to show progress of an page. for example 1- choose food, 2-choose drink, 3-choose payment method)
It feels like someone should have shared similar component somewhere, in the past but I cannot find the right name for my google question. Can someone help me with the right name for it or possibly give link to stackoverflow question about similar component?
You can use this https://bit.dev/primefaces/primereact/steps from https://bit.dev.
There should be also a lot of other useful components
I was trying to toggle the page with a buttonLink and list elements when I click on the buttonLink. I can basically see 2 popular possible approaches to this:
Using react router and create routes one for the list button and another for the list elements that opens up when clicking on on list button element which gets list elements as props in router
Pass the props to list element but render it in the same page, but with state toggle condition. Example -
this.state.showList===true ? :
Here I'm confused to decide between these 2 approaches. I preferably chose the 2nd approach to toggle between components based on state as I'm less comfortable with Router. But if the number of components in that page increases, it is difficult to maintain it using state value.
But I would like to know that standard approach for medium scale applications.
Any examples or pointers would be helpful, thanks.
I'm using both approaches and distinguish between encapsulated business logic and modifying logic. For example you have persons and relations between those persons. So I have 2 routes <personId>/details and <personId>/relations. With the first you will see person details like name, address, telephone numbers and with the second you see a network of related persons, who are connected with this person. For me I decide between those 2 approaches by what I expect to see after reloading the page (pressing F5). When I'm on the detail page I want to see the details again and also I want to see the relation network again.
But there are some modifying logics like adding a new a new telephone number. Normally you would do this by showing a modal dialog or expanding a form with some inputs and "OK"/"Cancel". When this dialog is opened and doing a page reload I would expect to see the person details again. So I'm implementing this dialog via {this.state.showAddTelephone && ...}
In my opinion just go with react-router. Routes are used in multiple areas of the app. The logic of conditional rendering can introduce too much complexity if it's being used in a lot of places. It would be easier to just take the declarative approach of the router with no logic behind it.
There are many answers regarding react component communication, but seems none of them resolved my problem. Here is my problem's detail. Please help! Thanks in advance.
I'm building a flexible form. The UI is generated by nesting components.
The form data structure could also be nested json objects.
i.e form can have some inputs and sections, sections can have some inputs or sections, and go on.
sections is just UI layout components, doesn't care about data or state.
But input (could be text input, checkbox etc anything to capture data)
The problem I'm facing is any input's validation could depends on any other inputs' value.
i.e inputA has validation expression like formData.inputB >formData.inputA + formData.inputC
But they could also have no dependency at all if you don't give a validation expression.
If I pass the whole formData down the component tree, every time I type in one input, the whole form will rerender.
I have considered redux, but real not sure how redux can help such case. I'm still relative new to react and redux, so I could be wrong.
So what could be a viable solution?
Its a common issue when you're modularizing form elements. I have the same problem.
Redux is by far the most controlled solution. All of the components can listen and update the same object simultaneously. But you can also attach functions as props from the parent that you bind to the parent. The function would fetch the state of the parent and update the state like a makeshift store. If you're a good developer, this is possible but neither are simple to do. Good time to learn :)
There are various solutions to your problem, but in general it shouldn't even be a problem, because rendering (even of large forms) should be quite effective with React.
The core tool for adjusting performance in React is the shouldComponentUpdate method of your component classes. If you're smart about what you pass to the individual form fields and then implement shouldComponentUpdate properly on them, you should be able to update only when needed. In your particular example, you don't need to pass the full object everywhere.
You can just pass value, onChange and isInvalid to each field and calculate the validity at the root (where you have access to the full state). Then the shouldComponentUpdate of your fields can decide just based on those props. (Obviously this is a simplistic example, but as a principle it's sound.)
Sure, Redux is another possible solution. If you keep the state in Redux store and only connect each of your fields to the portion of the state it needs, you should be all set. It brings quite a change in architecture though, so you should choose Redux only if you really want it for your app as a whole.
I'm debating refactoring parts of a site I'm working on from jQuery into react. Before I start I'd appreciate some feedback on my thought process so far.
<DeviceChooser>
<ManufacturerSelect />
<DeviceSelect />
<ButtonOne />
<ButtonTwo />
<DeviceChooser>
That is the desired component. It's behavior is:
The parent (DeviceChooser) gets some json data via ajax on componentWillMount.
It passes part of that data to ManufacturerSelect, which is a select field.
Once something is selected there, DeviceChooser passes some other data to DeviceSelect, which is also a select field.
Once something is selected there, if some conditions are met, both Button1 and Button2 become active
Clicking Button1 or Button2 would redirect the page to a specified url, with parameters set depending on the 2 select fields.
More practically speaking, you choose your phone manufacturer, then in the next select you choose your device from that manufacturer, then you get redirected to either page1 or page2 with some get parameters depending on the button you press.
My questions are:
Who's responsibility should it be to decide whether the buttons should be active? The DeviceChooser or the Buttons?
Who should compose the redirect URL? The Chooser or the Buttons?
I'm going to have variations of this DeviceChooser component all over the website, what can I do to ensure at least some reusability? The caveat being that sometimes it will have more select fields that just 2, and other times different select fields will be part of the equation depending on state (Like, if your device is a laptop, you also specify what shape of edges the device has)
I'm really grateful to any feedback at all. I've also created a Gist with the code I've come up with so far, if it helps.
One of the methodologies that I have followed since getting invested in React is using containers. Containers essentially are components that are responsible for retrieving and manipulating the data and then passing all the relevant data down to all the child "dumb" components that are simply responsible for rendering said data.
Operating under this premise (or something similar) I would suggest doing calculations in the container on the initial data, and pass everything down.
So in this instance we should be do the following in the container (or parent component)
Get JSON data via componentWillMount
Manipulate the data and pass it to ManufacturerSelect
The other questions depend on which framework you're using. Are you able to elaborate on this? Are you using Redux, Flux, ReFlux etc?
I've had a quick look at your code, one super useful thing that I think you should do is specify PropTypes for each component. This helps immensely for debugging, and when you're talking about reusing components in several distinct locations this will be crucial. Also (without understanding the full context) is it necessary to use state everywhere in your components? Would it be possible for them to simply render the props passed down to them? (again this depends a little on the store you'
re using).
It's a relatively generic question, but my line of thinking (quite opinionated) would be as follows:
Your Buttons should become simple, generic Button components that should for this example have the following props (besides perhaps some styling props):
disabled
title
onClick
Your Device Chooser is the one who's got the awareness that components mix together, that these buttons should actually continue to do something after they're clicked, so you'll want to handle that knowledge solely within that component. It glues the rest together (passes data around) and should therefore also make these decisions.
<DeviceChooser>
<ManufacturerSelect data={this.state.manufacturers} />
<DeviceSelect data={this.state.devices} />
<Button
disabled={this.state.selectedManufacturer === null ? true : false}
title='Manufactuer details'
onClick={this.handleManufacturerDetailsClick.bind(this, this.state.selectedManufactuer}}
/>
<Button
disabled={this.state.selectedDevice === null ? true : false}
title='See device details'
onClick={this.handleDeviceDetailClick.bind(this, this.state.selectedDevice }}
/>
<DeviceChooser>
Device chooser's method than can be something like:
handleDeviceDetailClick(device) {
history.pushState('/device/detail/' + device.id);
}
You want to separate your functional components from the stateless ones. A good read for this is http://tylermcginnis.com/functional-components-vs-stateless-functional-components-vs-stateless-components/