2

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

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
Ayush Agarwal
  • 295
  • 2
  • 16

2 Answers2

2

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

Ian Vasco
  • 1,280
  • 13
  • 17
  • i have tried this, it removes error but, selected value is undefined – Ayush Agarwal Sep 11 '19 at 14:10
  • `renderAddPackType(selectedOption, selectedIndex) { this.setState({ packTypeSelected: selectedOption.name }); console.log(selectedOption); } ` this solved the issue but the selection is getting some delayed after press in some millisec – Ayush Agarwal Sep 11 '19 at 14:19
  • Ah, good catch! What if you just use the callback method directly instead of using that proxy method `onSelectedItemsChange`. – Ian Vasco Sep 11 '19 at 14:29
  • can you please expand the sentence sir, – Ayush Agarwal Sep 11 '19 at 14:32
  • and also how can i set initial values i.e default values – Ayush Agarwal Sep 11 '19 at 14:32
  • `onSelection={(selectedOption, selectedIndex) =>this.props.callback(selectedOption, selectedIndex)}` yea i understood this point Thank you One more small help sir, how can i set up default values – Ayush Agarwal Sep 11 '19 at 14:39
  • 1
    What do you mean by set up default values? You already have specified the value that you wanted to be selected with `selectedOption` in `RadioButtons`. Also, please make sure to up vote the answer too if I was helpful :) – Ian Vasco Sep 11 '19 at 14:52
0

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.

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118