React - Fire modal from function [Solved]


#1

Hi All,

I’m trying to fire a modal from inside a react component. Having some trouble with the ES6 style JS (and generally react noob too).

import React from 'react';
import { Button } from 'react-bootstrap';

import { TestModal } from './testmodal.js';

const emailList = (userId) => {
  let emailAddresses = '';
  emailAddresses = userId.map(user => `${emailAddresses} <${user.address}>; `);
  return emailAddresses;
};

const handleUpdateUser = (userId, event) => {
  event.preventDefault();
  console.log(userId);
  // I want to call the Modal here
};

const handleDeleteUser = (userId, event) => {
  event.preventDefault();
  console.log(userId);
  // I want to call the Modal here
};

export const User = ({ user }) => (
  <tr key={ user._id }>
    <td>{ user.profile.name.first }</td>
    <td>{ user.profile.name.last }</td>
    <td>{ emailList(user.emails) }</td>
    <td>
      <Button
        bsStyle="warning"
        onClick={ handleUpdateUser.bind(this, user._id) }>
        Update
      </Button>
    </td>
    <td>
      <Button
        bsStyle="danger"
        onClick={ handleDeleteUser.bind(this, user._id) }>
        Delete
      </Button>
    </td>
  </tr>
);

User.propTypes = {
  user: React.PropTypes.object,
};

And my modal:

import React from 'react';
import { Modal, Button } from 'react-bootstrap';

export const TestModal = ({ user }) => (
  <Modal onHide={this.close}>
    <Modal.Header closeButton>
      <Modal.Title>{ user._id }</Modal.Title>
    </Modal.Header>
    <Modal.Body>
      <h4>Text in a modal</h4>
      <p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula.</p>
    </Modal.Body>
    <Modal.Footer>
      <Button onClick={this.close}>Close</Button>
    </Modal.Footer>
  </Modal>
);

TestModal.propTypes = {
  user: React.PropTypes.object,
};

The idea is to fire a function to handle the modal when user pushes a button. I want to call the modal from a function as this way i can have 1 generic modal component, and pass through whatever i need, including object user, and other simple bits of data.

Two questions:

  • How do i call the <TestModal (whatever props)/> from within the handleDeleteUser or handleUpdateUser functions?
  • Kind of Unrelated - How do i setup a constructor here (in either User or Modal), say i want to setup some bits of state or something.

Any ideas are very much appreciated. Thanks so much.

Tat


#2

Actually just a clarification. I figure there are two options.

  1. Add in the with its relevant props in the main User function. But its state is set to closed. Then use the correct handleWhateverUser function which will set its state to open. How do I setup the constructor in this case?
  2. Call the with relevant props from the hanldeWhateverUser function directly. How do i do this?

Option B is my preferred solution, because I want to be able to send lots of info to the Modal, the plan would be to make the Modal generic and reusable. Is this a pipe dream, mostly as I would be calling server side code to make changes to the db? I.e. making the modal generic is not doable as i want to tell it to be a form to change the users something (a button inside the modal that would save changes to edit a users profile).

Thanks so much.

Tat


#3

Just bumping this… not sure if no no in these parts. As always, preferable to ask for forgiveness…

Any ideas on above are super appreciated.

Tat


#4

Since you’re using react-bootstrap, have you taken a look at their Overlays docs? Take a look at the source of their “Basic example” in this section in particular, by clicking on the little “show code” link. This will show you the source of an example component that leverages a button to manipulate the showModal state, which in turn opens/closes the included modal (which is essentially what you want to do with your handleUpdateUser/handleDeleteUser functions).

You’ve defined your components as stateless functions so they don’t (and can’t) have constructors. If you want to use a constructor look into building your components with ES2015 class syntax. You can then set your initial state using a constructor function.


#5

Hey Hugh ,

Let me digest the above and will try to understand it better. I’ve only been coding for a few months and I think this is an light bulb moment. I knew stateless components were preferred for testing purposes, but had no idea how to use them (or that i was…).

I simply was writing code like some examples I saw, and you have just explained something really awesome. Much appreciate the pointer towards overlays also. Thank you very much.

Tat

P.S. - if you were to recommend a approach, stateless or ES2015 class syntax, which way would you go?


#6

Hi @hwillson,

Ok - so are you saying that the way I should think about this is use a normal ES2015 class syntax for the User component, and then put in the stateless functions under that and have User control state?

Cause the overlay docs require state to be set somewhere right, you can never be purely stateless?

Also, is the idea the lowest level components are stateless, but higher components should hold state. Or is it more a mix and match whatever works deal?

Thanks so much.

Tat


#7

That sounds reasonable to me. One of your components will need to control the modal open/close state, so the User component looks like a good candidate.

Right - the open/close state of the modal needs to be tracked somewhere. You can either track this via internal component state, or look into using some kind of external state container like Redux (if you’re just getting started though I’d recommend using internal component state to keeps things more simple for now).

It’s more a case of whatever works. The React team wants people to use stateless functions/components as much as possible moving forward as they’re much easier to performance optimize behind the scenes. That being said sometimes you need to track state and tracking it with an external state container like Redux isn’t really worth the extra complexity. When I’m working on React components I always start by building them with stateless functions, then change them to use ES2015 class syntax if I need to track state (or use any of the component lifecycle methods) for any reason.


#8

Hey mate,

Many thanks for the pointers above. I re factored the code to be stateful, and the modal is fine now.

I think I will go with the option of writing everything stateful, and then bottom up refactor to be stateless or use redux. This way the simpler functions are easy to test, and the more complex stuff gets refactored in a standard manner.

I need to do some more reading and some more work to understand the component lifecycle in react, but live and learn i guess.

Thanks so much.

Tat