0

I have the following reducer in my React app:

const initialState = {
    genderRadio : false,
    ageRadio : false
}

const reducer = (  state = initialState , action ) => {

    switch(action.type) {
        case "VALI_RADIO_INP":
            console.log(action.payload.target);
            return state        
    }
    return state;
}

export default reducer;

action.payload is basically the event object that is passed to the reducer, like so from my component:

validateRadioInput : (e) => dispatch({ type: 'VALI_RADIO_INP' , payload : e })

What I would like to do in my reducer is check if the input element has been checked or not and update the state. How do I using the event object check if a element is checked or not checked?

NOTE::-

Before integrating redux I was checking if the checkbox is checked calling a method that resided right inside my component like so:

Array.from(document.getElementsByName('customer_gender')).some( (elem , idx) => {  return elem.checked  }) 

But of course I can't use this anymore; any suggestions on how I can validate the checkbox in my reducer using the event object?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Alexander Solonik
  • 9,838
  • 18
  • 76
  • 174

2 Answers2

1

First set attribute name to your checkbox element like so:

<input type="checkbox" name="genderRadio"/>

or:

<input type="checkbox" name="ageRadio"/>

And modify your code that set correct piece of state depending on the attribute name of checkbox element. Example:

const reducer = (  state = initialState , action ) => {

switch(action.type) {
    case "VALI_RADIO_INP":
        console.log(action.payload.target);
        return { ...state, [payload.target.name]: payload.target.checked };        
 }
  return state;
}

export default reducer;
Artem Mirchenko
  • 2,140
  • 1
  • 9
  • 21
1

How do i using the event object check if a element is checked or not checked ?

You shouldn't do that. Your Redux reducers shouldn't be coupled to the DOM if you can help it. Though, it is possible that you can traverse the DOM from the event's target, if you're using React you shouldn't be depending on the DOM at all.

One way to do it is to get your component to have a data representation of the view. This could be your React component's state. Or, you could grab it from the DOM if you're not using React with something like this:

validateRadioInput: (e) => {
  const checkedArr = Array.from(document.getElementsByName('customer_gender'))
      .map(elem => elem.checked);

  return dispatch({
    type: 'VALI_RADIO_INP',
    payload: checkedArr,
  });
}

// reducer
const reducer = (  state = initialState , action ) => {

    switch(action.type) {
        case "VALI_RADIO_INP":
            const valid = action.payload.some(checked => checked);
            return { ...state, valid };        
    }
    return state;
}

Ultimately, though, I don't agree with the concept of doing form validation sort of logic in Redux -- just do it in the component and then dispatch some action to Redux if it's valid. Redux shouldn't have to deal with every nitty-gritty state in your application; just state that affects multiple components in potentially complex ways.

Also, note that you may be trying to fix an HTML problem in JS since you can only check one radio button at a time, anyway, and you could just make the HTML have a required field. See HTML5: How to use the "required" attribute with a "radio" input field

Kevin Raoofi
  • 1,023
  • 11
  • 16