Search code examples
javascriptreact-nativestate-managementreact-context

Using context in React Native to render TextInput values


Trying to create the functionality where you have a globally accessible array of values, that can be inputted by a user and then outputted and/or edited in different components.

I've been able to create an object array in one screen and have it output fine, but i need the same array to be shown in another screen for the options to be selectable.

I keep getting this error:

Error: Objects are not valid as a React child (found: object with keys {dispatchConfig, _targetInst, _dispatchListeners, _dispatchInstances, type, target, currentTarget, eventPhase, bubbles, cancelable, timeStamp, defaultPrevented, isTrusted, touchHistory, nativeEvent, isDefaultPrevented, isPropagationStopped}). If you meant to render a collection of children, use an array instead.

a lot of the search results end up not applying to my particular issue unfortunately as far as i can tell.

WeightContext.js :


const WeightContext = createContext();

const WeightProvider = (props) => {
    const [weights, setWeights]= useState([]);
    return (
        <WeightContext.Provider value={[weights, setWeights]}>
            {props.children}
        </WeightContext.Provider>
    );
}
export { WeightContext, WeightProvider };

App.js :

import React from 'react';
import { View, Text } from 'react-native';
import {styles} from './styles/styles';
import { WeightProvider } from './contexts/WeightContext';
import Header from './components/Header';
import AddWeight from './components/AddWeight';
import WeightList from './components/WeightList';

const App = () => {

    return (
      <WeightProvider>
        <View style={styles.container}>
          <Text style={styles.headings}>App Component</Text>
            <Header />
            <AddWeight />
            <WeightList />  
        </View>
      </WeightProvider>
    );
}

export default App;

Header.js

import React, { useContext } from 'react';
import { View, Text } from 'react-native';
import { WeightContext } from '../contexts/WeightContext';
import { styles } from '../styles/styles';

const Header = () => {
    const [weights, setWeights] = useContext(WeightContext);

    return (
        <View style={styles.screen}>
            <Text style={styles.subHeading}>Weight Amounts List</Text>
            <Text style={styles.paragraph}>Total entries in weights: {weights.length}</Text>
        </View>
    );
}

export default Header;

WeightList.js:

import { View, Text } from 'react-native';
import Weight from './Weight';
import { WeightContext } from '../contexts/WeightContext';
import { styles } from '../styles/styles';

const WeightList = () => {
    const [weights, setWeights] = useContext(WeightContext)

    return (
        <View>
            <Text style={styles.subHeading}>Weight List</Text>
            {weights.map((item) => {
                return (
                    <Weight amount={item.amount} key={item.id}/>
                );
            })}
            
        </View>
    );
}

export default WeightList;

AddWeight.js

import React, { useContext, useState } from 'react';

import { View, Text, TextInput, Button } from 'react-native';
import { WeightContext } from '../contexts/WeightContext';
import { styles } from '../styles/styles';

const AddWeight = (onAddAmount) => {
    const [weights, setWeights] = useContext(WeightContext)

//// variables
    const [amount, setAmount] = useState('');

/// functions    
    const updateAmount = (valueEntered) => {
        setAmount(valueEntered);
    };

    const addAmountHandler = (amount) => {
        setWeights((prevWeights) => {
            return [...prevWeights, {id: Math.random().toString(), amount: amount}];
        });
    }

    return (
        <View style={styles.screen}>
            <Text>Add Weight</Text>
            <TextInput 
                placeholder="Add new Amount"
                maxLength={2}
                keyboardType={'numeric'}
                value={amount}
                onChangeText={updateAmount}
            />
            <Button title="ADD NEW WEIGHT" onPress={addAmountHandler}/>
        </View>
    );
}

export default AddWeight;

Weight.js

import React from 'react';
import { View, Text } from 'react-native';
import { styles } from '../styles/styles';

const Weight= ({amount}) => {

    return (
        <View style={styles.screen}>
            <Text style={styles.paragraph}>{amount}</Text>
        </View>
    );
}

export default Weight;

Thanks in advance!


Solution

  • Replace this: const addAmountHandler = (amount) => {...}

    with this: const addAmountHandler = () => {...}