Rendering material-ui-next Checkbox inside a Redux

2020-04-20 08:31发布

问题:

I am having some trouble trying to render a simple material-ui-next checkbox inside a redux-form. I am following the official example and trying to adapt it to the material-ui-next equivalent, since the example is using the older version of material-ui. This is the code that I end up using:

const renderCheckbox = ({ input, label }) => (
  <FormGroup row>
    <FormControlLabel
      control={
        <Checkbox
          checked={input.value ? true : false}
          onChange={input.onChange}
          value="checkedA"
        />
      }
      label="Secondary"
    />
  </FormGroup>
);

And this is how I define the checkbox inside redux-form:

...
<Field name="activated" component={renderCheckbox} label="Activated" />
...

However when I save the code, React is complaining with the following error:

index.js:2178 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check your code at myForm.js:108.

Line 108 of the code is the <Checkbox /> component that is defined inside the aforementioned renderCheckbox() method.

回答1:

I was also stuck on this issue for quite some time when I finally found a fix to this. It never works for a functional component which returns a check box. I made a separate class component and wrapped it in Redux Field component and it worked perfectly. I really never understood why it didn't work for the fucntional component as it what is shown in their official example.

I have written the code that worked for me. Hope it helps :)

class CheckBoxInput extends React.Component {

  onCheckBoxSelectChange = (input) => 
  {
    input.onChange();
    this.props.onSelectChange();
  }

  render() {
    const { label, input,} = this.props;
    let name = input.name;

    return (
      <div>
        <InputLabel htmlFor={label} style={{paddingTop: '15px'}}> {label} </InputLabel>
         <FormControl {...input} >
          <Checkbox
            name = {name}
            label = {label}
            color= "primary"
            checked={input.value ? true : false}
            onChange={() => this.onCheckBoxSelectChange(input)}
          />          
        </FormControl>
      </div>

    )
  }
}

const CheckBox = (props) => <Field component={CheckBoxInput} {...props} />;
export default CheckBox;

And to use this checkbox component:

 <CheckBox  name="isCurrent" label="Current" onSelectChange = {this.toggleCurrentEmployerSelection} />