2

I was creating a Dropdown component for React. Inside the dropdown, I have a form of radio group buttons.

<DropdownButton />
  <DropdownForm />

In the DropdownButton, I have an state to know if it is open or not. Depends on that, DropdownForm it's hidden or not (using display: none).

The use case is: User selects a radio button, click apply and something happen. However, if user selects some radio button, and mouse out the dropdown (without clicking the apply button), the one that is selected should be the one that I get from the store.

Something like:

render: function () {
  ...

  if(store.getSomeParam() != this.state.someParam && !this.props.isOpen){
    someParam = store.getSomeParam()
  }

Then the radio buttons are like:

<input checked={someParam == "something"} ... />

It doesn't really work. It re-renders but it doesn't change the button that is checked. I also tried with refs:

this.refs.myInput.getDOMNode().checked = true

But still nothing. Is this a correct behaviour?

The only solution I found so far is not using a css hiding class (display: none). So what I do is that the DropdownButton renders the DropdownForm depending on if it's open or not (so if you close it, you are forcing DropdownForm to unmount). Then when opening again, it is taking the values from the store (getInitialState) and it shows the correct radio button selected. But, I am not sure if this is the best solution and if there is any drawback in unmounting the component instead of just css hiding it.

2 Answers 2

1

This probably has nothing to do with React at all.

Most browsers don't validate the value of the checked attribute, but merely if it is there or not: http://jsfiddle.net/7jzm7gvw/

Just set the checked attribute to either true or null:

<input checked={someParam == "something" ? true: null} ... />
Sign up to request clarification or add additional context in comments.

Comments

1

TL;DR: You must use the componentDidMount lifecycle method, not render, to work with the rendered dom nodes directly.

I was struggling with this as well, and after doing some online research I figured I might as well look into it for myself. Here's what I came up with:

Use the componentDidMount lifecycle method and update whatever you need to in there. Here's a Pen I used to prototype this, and I think it looks okay: http://codepen.io/gholts/pen/GpWzdb

You could drop this in pretty easily to what your'e working on by just putting a componentDidMount method on your object and doing it there. I used document.getElementById but you could definitely use jQuery or whatever else you wanted in there, as once the component has mounted it's available to DOM selectors.

I'm using this now to update 20 radio button groups (so it has to check a prop for three different states and update accordingly) and it loads instantly.

Hope it helps! I used the ES6 class syntax in my Pen, you should check it out if you have some time to refactor :) It's fun.

EDIT: So I figured it out, I'm a dummy. You don't need to do the whole document.getElementById business that I was doing. Just use your this.refs.whichever.getDOMNode().checked = true and it'll work, so long as you do it in componentDidMount. It works there because there is an actual DOM element on the page at that point.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.