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?
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>
)
}
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');
}}