I'm trying to use React Context to pass a function to a nested child component, which effectively allows the child to update the parents state when pressed.
The problem is I seem to be getting an error 'TypeError: render is not a function. (In render(newValue), render is an instance of Array' and an error in my console reads: 'Warning: A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it.'
I've looked around at this error and also at documentation but no answers seem to answer my question, I can't quite work out why this isn't working.
EDIT: I should add that there are multiple child components rendered, as they're built from an array of objects
Snippets:
Parent:
class Product extends Component {
state = {
selected_ind: 0
};
handleContextChange = selected_ind => {
this.setState({selected_ind});
};
render() {
const contextValue = {
data: this.state,
handleChange: this.handleContextChange
};
//Desconstruct props for ease of use
const {
attr_data,
variant,
product_name } = this.props;
return (
<Container>
<Heading>Product Options</Heading>
<IndexContext.Provider value={contextValue}>
<OptionTile
tileColor='grey'
onPress={ () => this.props.navigation.navigate('Variants', {
attr_data: attr_data,
selected_ind: this.state.selected_ind
})} //Replace with named function
option="Variant"
selected_ind={ this.state.selected_ind }
value={ selected_attr.name } />
</IndexContext.Provider>
<OptionTile
tileColor='grey'
option="Quantity"
value="1" />
</Container>
Within OptionTile is the child I'd like to use the function within:
const VariantTile = (props) => {
return (
<IndexContext.Consumer>
{({ handleChange }) => (
<TouchableOpacity onPress={handleChange(props.index)}>
<AsyncImage
source={ props.img_src }
placeholderColor="#fafafa"
style={{ flex: 1, width: null, height: 200 }}
/>
<Text>{ props.var_name }</Text>
<Text>{ props.price }</Text>
<Text>{ props.sku }</Text>
</TouchableOpacity>
)};
</IndexContext.Consumer>
)
};
And the context component is simple:
const IndexContext = React.createContext();
export default IndexContext;