VesterDe
VesterDe

Reputation: 160

Am I thinking in in react correctly about form behaviour

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:

  1. The parent (DeviceChooser) gets some json data via ajax on componentWillMount.
  2. It passes part of that data to ManufacturerSelect, which is a select field.
  3. Once something is selected there, DeviceChooser passes some other data to DeviceSelect, which is also a select field.
  4. Once something is selected there, if some conditions are met, both Button1 and Button2 become active
  5. 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:

  1. Who's responsibility should it be to decide whether the buttons should be active? The DeviceChooser or the Buttons?
  2. Who should compose the redirect URL? The Chooser or the Buttons?
  3. 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.

Upvotes: 0

Views: 41

Answers (2)

janpieter_z
janpieter_z

Reputation: 1742

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/

Upvotes: 0

JamesWatling
JamesWatling

Reputation: 1185

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).

Upvotes: 1

Related Questions