0

While I'm learning React, I started creating a rather simple project. A journey planner for TFL (Transport For London). The app gets some parameters such as From, To, and mode (Tube, Bus, Overground) and sends an API request to TFL API.

The mode data is being put together by 3 checkboxes, tube, bus and overground. It should be send as a string with commas between each word. Something like tube,bus,overground or only bus,overground etc.

This is the way I'm handling the checkbox values:

// Handling checkboxes
    const tubeVal = e.target.elements.tube.checked === true ? "tube" : "";
    const busVal = e.target.elements.bus.checked === true ? "bus" : "";
    const overgroundVal = e.target.elements.overground.checked === true ? "overground" : "";

    let mode = "";
    if (tubeVal && !busVal && !overgroundVal) {
      mode = tubeVal;
    }
    if (!tubeVal && busVal && !overgroundVal) {
      mode = busVal;
    }
    if (!tubeVal && !busVal && overgroundVal) {
      mode = overgroundVal;
    }
    if (tubeVal && busVal && !overgroundVal) {
      mode = tubeVal + "," + busVal;
    }
    if (tubeVal && !busVal && overgroundVal) {
      mode = tubeVal + "," + overgroundVal;
    }
    if (!tubeVal && busVal && overgroundVal) {
      mode = busVal + "," + overgroundVal;
    }
    if (tubeVal && busVal && overgroundVal) {
      mode = tubeVal + "," + busVal + "," + overgroundVal;
    }

Is it the right way to handle checkbox data in React? It doesn't seem right to me.

2 Answers 2

1

Your code could be heavily shortened to a single line :

const mode = ['tube', 'bus', 'overground'].filter(key => e.target.elements[key].checked).join(',');

We first make an array with every elements name you wish to take, filter out the ones that are not checked, and compose our final strings with all the remaining names put together with a , using join.

You can now store the mode variable in you state for later use in your render.

Working demo :

function test(e) {
    const mode = ['tube', 'bus', 'overground'].filter(key => e.target.elements[key].checked).join(',');

    console.log('Mode : ', mode);
    return mode;
}

test({ target: { elements: { 
    tube: { checked: true },
    bus: { checked: false },
    overground: { checked: true }
} } })

test({ target: { elements: { 
    tube: { checked: true },
    bus: { checked: true },
    overground: { checked: true }
} } })

test({ target: { elements: { 
    tube: { checked: true },
    bus: { checked: true },
    overground: { checked: false }
} } })

test({ target: { elements: { 
    tube: { checked: false },
    bus: { checked: false },
    overground: { checked: false }
} } })

Sign up to request clarification or add additional context in comments.

2 Comments

My God! How cool is that? Thanks @Treycos. Do I really need to save mode in state? In this simple project, I don't need to pass them to any other component. Should I still save it in store?
Well, nothing is forcing you to, it entirely depends on what you want to achieve with it. Since you are using the redux store you could put it there
0

I would create an array of the field names i want, then filter the checked ones and then add their values in an array and join with ,.

Something like this

function handleCheckboxes(e) {
  e.preventDefault();
  // Handling checkboxes
  const checkboxes = ['tube', 'bus', 'overground'];
  const nodes = checkboxes.map(name => e.target.elements[name]);
  const values = nodes.filter(node => node.checked).map(node => node.value);
  const mode = values.join(',');
  alert(mode);
}

// for demo
document.querySelector('form').addEventListener('submit', handleCheckboxes);
<form>
  <input type="checkbox" name="tube" value="tube" />
  <input type="checkbox" name="bus" value="bus" />
  <input type="checkbox" name="overground" value="overground" />

  <button type="submit" id="check">check</button>
</form>


Specifically for React, you could have a container Component which renders and controls the three checkboxes and their state (checked or not) by storing it it the state. Then you can get those values, and again create an array from them and join with ,.

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.