Issue with creating a simple food list app by redux in react native

roz333 :

I am trying to create a simple food list app, I want the user write the name of food in textinput ( in input screen) and click on submit button then those name that have been written get printed in another screen ( named foodlist screen), All states are going to work via redux.

I have two problems:

1: Submit button doesn't work, it means when user start to typing in text input all letters get printed, I want it happen when user click on submit button

2:If user type a five letter word, Redux print five items in foodlist screen ( like has shown in folowing pic)

How can i fix this?

enter image description here

enter image description here

This the reducer code:

import {
    ADDFOOD,
    REMOVEFOOD,
    CLEANTEXT




} from '../actions/types';

initialState = {

    foodList: []

}




export const foodReducer = (state = initialState, action) => {

    switch (action.type) {
        case ADDFOOD:
            return {
                ...state,
                foodList: state.foodList.concat({
                    name: action.payload,
                    index: Math.random()
                })
            }
            break;
        case REMOVEFOOD:
            return {
                ...state,
                foodList: state.foodList.filter((item) =>
                    item.index !== action.payload

                )
            }
            break;

        case CLEANTEXT:
            return {
                ...state,
                foodList: ''
            }
            break;

        default:
            return state;
    }



}

This is the text input code:

import { useSelector, useDispatch } from 'react-redux';
import { addFood, cleanText } from '../actions';



const Login = (props) => {

  const { navigation } = props;
  const foodList = useSelector(state => state.foodR.foodList);

  const dispatch = useDispatch();

  return (


    <View style={styles.container}>

      <Text style={{ color: 'black', fontSize: 20 }}>Login Form</Text>

      <TextInput
        style={styles.input}
        placeholder='Food name'
        onChangeText={(value) => dispatch(addFood(value))}
        value={foodList}





      />

      <TouchableOpacity
        activeOpacity={0.8}
        style={styles.button}


      >

        <Text style={{ color: 'white', textAlign: 'center' }}>Submit</Text>

      </TouchableOpacity>
      <TouchableOpacity
        activeOpacity={0.8}
        style={styles.button}
        onPress={() => {

          navigation.navigate('FoodList');

        }}

      >

        <Text style={{ color: 'white', textAlign: 'center' }}>Go to Food list</Text>

      </TouchableOpacity>








    </View>






  )

}

And this is the foodlist code:

import { useSelector, useDispatch } from 'react-redux';
import { removeFood } from '../actions';






const FoodList = () => {



    const foodList = useSelector(state => state.foodR.foodList);
    const dispatch = useDispatch();





    return (

        <View style={styles.mainContainer}>
            <View style={styles.container}>
                <FlatList
                    data={foodList}
                    keyExtractor={(item, index) => index}
                    renderItem={({ item, index }) => (

                        <TouchableOpacity
                            style={styles.button}
                            activeOpacity={0.7}
                            onPress={(index) => dispatch(removeFood(item.index))}
                        >


                            <Text style={{ fontSize: 20, marginLeft: 10 }} >{item.name}</Text>


                            <Icon type='FontAwesome5' name='trash' style={{ fontSize: 25, marginRight: 10 }} />
                        </TouchableOpacity>

                    )} />

            </View>
        </View>

    )

}
Michael Ceber :

You are calling the action every time the text changes

onChangeText={(value) => dispatch(addFood(value))}

What you want to do is store the value not in redux but in local state using the hook useState()

Then when submit is pressed add a line which takes the latest state stored locally and dispatches this to redux:

onPress={() => {
   // get the local state and call dispatch(removeFood(item.index))
   navigation.navigate('FoodList');
}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=31685&siteId=1