2
votes

im trying to implement radio buttons into my react native project with a callback from the component

Im using react-native-radio-buttons SegmentedControls into the project

App.js

import files....
import RadioButtons from "../components/RadioButtons";

//Data
const PackingType = [{id:"1", name: "Bag"},{id: "2",name: "Box"}];

export default class App extends Component {
constructor(props) {
    super(props);
    this.state = {
      packTypeSelected: [],
    };
  }
...

  renderAddPackType(selectedOption, selectedIndex) {
    this.setState({ selectedIndex });
    console.log(selectedIndex[0]);
  }

...
render(){
return(
...

 <RadioButtons
            buttonOptions={PackingType}
            callback={this.renderAddPackType.bind(this)}
            selectedOption={"Bag"}
          />

...
)
}

RadioButtons.js

import { SegmentedControls } from "react-native-radio-buttons";
export default class RadioButtons extends Component {
  onSelectedItemsChange = (selectedOption, selectedIndex) => {
    this.props.callback(selectedOption, selectedIndex);
  };

  render() {
    return (
      <View style={{ marginHorizontal: 20, marginVertical: 10 }}>
        <SegmentedControls
          options={this.props.buttonOptions}
          onSelection={(selectedOption, selectedIndex) =>
            this.onSelectedItemsChange(selectedOption, selectedIndex)
          }
          selectedOption={this.props.selectedOption}
        />
      </View>
    );
  }
}

Error:

 Invariant Violation: Invariant Violation: Objects are not valid as a React child (found: object with keys {id, name}). If you meant to render a collection of children, use an array instead.

im not much experienced in development so far.. kindly help with the mistakes done here

Thank you for your time

2

2 Answers

2
votes

So, I was reading the documentation from react-native-radio-buttons and just found out that

You can also specify how to extract the labels from the options through the extractText prop

Which is clearly missing from your code. Here is what they expect you to do

  <SegmentedControls
    options={this.props.buttonOptions}
    onSelection={(selectedOption, selectedIndex) =>
      this.onSelectedItemsChange(selectedOption, selectedIndex)
    }
    selectedOption={this.props.selectedOption}
    extractText={ (option) => option.name }
    testOptionEqual={(selectedValue, option) => selectedValue === option.name}
  />

I haven't tried it but I think it would work

0
votes

According to the error, SegmentedControls attribute options accept a ReactNode, and you assigning an array Object.

Change the PackingType type to ReactElement, for example:

// Array Object - throws an error
const PackingType = [{id:"1", name: "Bag"},{id: "2",name: "Box"}];

// ReactNode example
const PackingType = (
  <div>
    {[{ id: "1", name: "Bag" }, { id: "2", name: "Box" }].map(type => (
      <div key={type.id}>{type.name}</div>
    ))}
  </div>
);

// Assigning as props
<RadioButtons
  buttonOptions={PackingType}
  callback={this.renderAddPackType.bind(this)}
  selectedOption={"Bag"}
/>

// Using them inside SegmentedControls
<View>
  <SegmentedControls
    options={this.props.buttonOptions}
  />
</View>

Note that I didn't check what SegmentedControls accepts in options attribute, it may be array of ReactNodes or something else, just recheck it because you assigning the wrong type.