undefined is not a function(near '...datas.map....') - javascript

This is my data
[{"size":"Small","price":"90"},{"size":"Large","price":"180"},{"size":"Extra Large","price":"200"}]
and this is my code
const route = useRoute();
const [datas, setDatas] = useState([]);
useEffect(() => {
setDatas(route.params.item_sizes);
},[])
const ItemSizes = () => {
if(datas.length > 0)
{
console.log("Item size data: ", datas); //for debugging purposes
return(
<View>
{datas.map((data,key) => (
<View key={key}>
<View style={{flex:0.2}}>
<MaterialCommunityIcons name={"radiobox-blank"} size={20} color={'gray'}/>
{/* <Text style={{fontSize:16, fontWeight:'bold'}}>Icon</Text> */}
</View>
<View style={{flex:1}}>
<Text style={{fontSize:16, fontWeight:'bold'}}>{data.size}</Text>
</View>
<View style={{flex:1, flexDirection:'row-reverse'}}>
<Text style={{fontSize:16, fontWeight:'bold'}}>{data.price}</Text>
</View>
</View>
))}
</View>
)
}
}
I call it from my view like this
return (
<View>
{ItemSizes()}
</View>
)
So after I checked there's a data on datas so why it is undefined? Please do explain why it is returning me undefined even though there's a data?? Thank you

Check if the data you are setting is an array or string. If it's string set it like below by parsing
setData(JSON.parse(route.params.item_sizes));

Related

How to pass up nested state and avoid useCallback in react native

I have a parent and nest child component hierarchy of QuestionsAndAnswersScreen -> QuestionInput -> QuestionSelector -> AnswerSelector. I need to pass the question and answer object back up to the QuestionAndAnswerScreen in order to show it on the view. However I cannot find a way without going into deep nested callbacks.
Here is my code for the QuestionAnswerScreen and AnswerSelector:
function QuestionsAndAnswers() {
const {shell, body} = styles;
return (
<View style={shell}>
<SignUpHeader title="Add your answers" page={5}/>
<View style={body}>
{qAndA[1] ? <Answer question={qAndA[1].question} answer={qAndA[1].answer}/> : <QuestionInput />}
{qAndA[2] ? <Answer question={qAndA[2].question} answer={qAndA[2].answer}/> : <QuestionInput />}
{qAndA[3] ? <Answer question={qAndA[3].question} answer={qAndA[3].answer}/> : <QuestionInput />}
</View>
<SignUpFooter
title={`Questions\n& Answers`}
buttonTitle={"Done"}
disabled={false}
route="QuestionsAndAnswers"
/>
</View>
);
}
function AnswerInput(props: AnswerInputProps) {
const {question, visible, answerModalVisible} = props;
const {pickAnAnswer, doneButton, answerTextInput, questionStyle, shell, buttonText} = styles;
const [modalVisible, setModalVisible] = useState(visible)
const [answer, setAnswer] = useState('');
const navigation = useNavigation();
useEffect(() => {
setModalVisible(visible)
}, [visible])
function answerQuestion() {
setModalVisible(false);
navigation.navigate('QuestionsAndAnswers');
}
return (
<View>
<Modal style={shell}
isVisible={modalVisible}
onBackdropPress={() => {
setModalVisible(false);
answerModalVisible(false);
}}
>
<View>
<Text style={pickAnAnswer}>Add answer</Text>
</View>
<View>
<Text style={questionStyle}>{question}</Text>
</View>
<View>
<TextInput
style={answerTextInput}
placeholder="Add your answer here..."
placeholderTextColor="#878787"
onChangeText={(text: string) => setAnswer(text)}
/>
<View style={{alignItems: 'flex-end', marginTop: 44}}>
<TouchableOpacity style={doneButton} onPress={() => answerQuestion()}>
<Text style={buttonText}>
Done
</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</View>
);
}
As you can see I get my Question and Answer in the AnswerInput but then need to navigate back to the main screen in order to display them. Any help would be great thanks :)

how to have more than one switch?

I am trying to have more than one switch on the same page, I succeeded but the problem is that when I click on a switch it modifies all the other switches.
Here is my code
const Setting =() => {
const [switchValue, setSwitchValue] = useState(false);
const toggleSwitch = (value, nb) => {
setSwitchValue(value);
};
return (
<View>
<View style={styles.Container}>
<Text style={styles.Title}>Change Profil Setting</Text>
</View>
<View style={styles.ContainerText}>
<Text syle={styles.Normal}>Over 18:</Text>
<Switch
style={{left: 50}}
onValueChange={toggleSwitch}
value={switchValue}
/>
</View>
<View style={styles.ContainerText}>
<Text syle={styles.Normal}>AutoPlay:</Text>
<Switch
style={{left: 50}}
onValueChange={toggleSwitch}
value={switchValue}
/>
</View>
<View style={styles.ContainerText}>
<Text syle={styles.Normal}>FlexDirecttion:</Text>
<Switch
style={{left: 50}}
onValueChange={toggleSwitch}
value={switchValue}
/>
</View>
</View>
)
}
const Setting =() => {
const [switchValue, setSwitchValue] = useState(false);
const [switch2Value, setSwitch2Value] = useState(false);
const [switch3Value, setSwitch3Value] = useState(false);
const toggleSwitch = (value, nb) => {
setSwitchValue(value);
};
const toggle2Switch = (value, nb) => {
setSwitch2Value(value);
};
const toggle3Switch = (value, nb) => {
setSwitch3Value(value);
};
return (
<View>
<View style={styles.Container}>
<Text style={styles.Title}>Change Profil Setting</Text>
</View>
<View style={styles.ContainerText}>
<Text syle={styles.Normal}>Over 18:</Text>
<Switch
style={{left: 50}}
onValueChange={toggleSwitch}
value={switchValue}
/>
</View>
<View style={styles.ContainerText}>
<Text syle={styles.Normal}>AutoPlay:</Text>
<Switch
style={{left: 50}}
onValueChange={toggle2Switch}
value={switch2Value}
/>
</View>
<View style={styles.ContainerText}>
<Text syle={styles.Normal}>FlexDirecttion:</Text>
<Switch
style={{left: 50}}
onValueChange={toggle3Switch}
value={switch3Value}
/>
</View>
</View>
)
}
This can be considered as a work around. What I would suggest is wrap the Switch component inside another component and import it where-ever you want by incorporating the state management in that component.

localStorage doesn't work in TouchableOpacity tag

I want to use localStorage and move to another page at the same time, but only moving work, I can't get the value
const pressHandlerMapTest = () => {
navigation.navigate("TestMapScreen");
};
return (
<ImageBackground style={styles.background}>
<View style={styles.tourWindow}>
<TouchableOpacity underlayColor="red"
onPress={pressHandlerMapTest}
onPressIn={() => {
localStorage.setItem('tour', 'others');
}}>
<Image source={require("../assets/royals.png")} ></Image>
</TouchableOpacity>
</View>
</ImageBackground>
);
const pressHandlerMapTest = () => {
localStorage.setItem('tour', 'others');
navigation.navigate("TestMapScreen");
};
return (
<ImageBackground style={styles.background}>
<View style={styles.tourWindow}>
<TouchableOpacity underlayColor="red"
onPress={pressHandlerMapTest}
>
<Image source={require("../assets/royals.png")} ></Image>
</TouchableOpacity>
</View>
</ImageBackground>
);

Why external function can't navigate other javascript file in React?

I'm making simple app which contains Todo App.
However, the function which locate in outside of main function(Is this expression right?) in same Javascript file can't navigate to other screen.
Below is my Screen structure(simplified)
<Stack.Screen name="Myqtwrite" component={MyqtwriteScreen} options={{headerShown: false}} />
<Stack.Screen name="Myqtupdate" component={MyqtupdateScreen} options={{headerShown: false}} />
And the problem is below.
I expressed the location of problem.
MyqtwriteScreen.js
export function Note(props, {navigation, route}) {
return (
<View style={[styles.myblock, {backgroundColor:props.val.color}]}>
<View style={{alignItems:'flex-start'}}>
<View style={{borderBottomWidth:2,borderColor:'white',marginBottom:5}}>
<Text style={[styles.myblocktitle]}>{props.val.date}</Text>
</View>
<Text style={styles.myblocktext}>{props.val.note}</Text>
</View>
<View style={{width: '100%' ,flexDirection:'row',justifyContent:'flex-end'}}>
/* problem is here--> */ <TouchableOpacity onPress={() => {navigation.navigate('Myqtupdate') }} style={{marginTop:5,marginLeft:10}} >
<Text style={styles.myblockbuttontext}>UPDATE</Text>
</TouchableOpacity>
<TouchableOpacity onPress={props.deleteMethod} style={{marginTop:5,marginLeft:10}} >
<Text style={styles.myblockbuttontext}>DELETE</Text>
</TouchableOpacity>
</View>
</View>
);
}
export function MyqtwriteScreen({ navigation, route }) {
const [noteArray, setNoteArray] = useState([]);
const [noteText, setNoteText] = useState('');
let rdcolor = 'hsl('+Math.random()*255+','+ Math.random()*(60)+10+'%, 82%)';
let notes = noteArray.map((val, key) => {
console.log('start');
return <Note key={key} keyval={key} val={val}
deleteMethod={() => deleteNote(key)} />
});
const addNote = () => {
if (noteText) {
var d = new Date();
noteArray.unshift({
'date': d.getFullYear() +
"Y " + (d.getMonth() + 1) +
"월 " + d.getDate() + "일 " + d.getHours() + "시 " + d.getMinutes()+"분",
'note': noteText,
'color': rdcolor,
});
setNoteArray(noteArray);
setNoteText('');
// alert('큐티 입력을 완료했습니다.');
}
else {
alert('큐티를 입력하세요');
}
};
const deleteNote = (key) => {
const newArray = [...noteArray];
newArray.splice(key, 1);
setNoteArray(newArray);
};
return (
<View style={styles.container}>
<View style={styles.topbar}>
<Text style={styles.topbartext}>오늘의 큐티</Text>
<Icon style={styles.topbarmenu} name="close" onPress={() => { navigation.navigate('My') }} />
</View>
<View style={styles.qtinputblock}>
<TextInput
onChangeText={(noteText) => setNoteText(noteText)}
value={noteText}
placeholder='큐티를 입력하세요'
placeholderTextColor='gray'
multiline={true}
style={styles.qtinputtext}
/>
<TouchableOpacity onPress={addNote} style={styles.myblockbutton}>
<Text style={styles.myblockbuttontext}>추가</Text>
</TouchableOpacity>
</View>
<ScrollView style={styles.scroll}>
<View style={{alignItems:'flex-start'}}>
{notes}
</View>
</ScrollView>
</View>
);
}
I made 'MyqtupdateScreen.js' file of course.
The most interesting thing is that when I wrote same onPress={() => {navigation.navigate('Myqtupdate') }} in some TouchableOpacity in the 'function MyqtwriteScreen({navigation, route'})' , it works!!
I don't understand why navigation.navigate('Myqtupdate') doesn't work in export function Note, but works in export function MyqtwriteScreen.
Any words would be help!
Note doesnt get a navigation prop you will have to pass it like below
return <Note key={key} keyval={key} val={val} navigation={navigation} deleteMethod={() => deleteNote(key)} />
It works on the other screen as its part of the stack.
You can also use the useNavigation hook to get access to navigation.

How can i set focus to only one TextInput in list item after TouchableOpacity pressed in this item?

I have a list of many items where each item has TextInput and TouchableOpacity wrapped by View.
I've trying to set focus on TextInput in the list item in which TouchableOpacity has been pressed. It's needed for editing each item's name.
Below is the code of how I tried to do this. The problem of this code is that after pressing on any of the TouchableOpacity the last TextInput will always be focused due to the fact that the last iteration overwrites textInputRef.
Is there a way to make textInputRef contain a reference to the TextInput which TouchableOpacity will press?
const ListComponent = ({list}) => {
const textInputValue = useRef('');
const textInputRef = useRef(null);
changeItemName = (text) => {
textInputValue.current = text;
};
return (
<ScrollView>
{list.length > 0 &&
list.map((item) => (
<View key={item._id}>
<TouchableOpacity>
<View
<Text>{`Item: `}</Text>
<TextInput ref={textInputRef} onChangeText={changeItemName}>
{item.name}
</TextInput>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
textInputValue.current = '';
}}>
<Icon name={'check'} size={25} color="#000" />
</TouchableOpacity>
<View>
<TouchableOpacity
onPress={() => {
textInputValue.current = item.name;
textInputRef.current.focus();
}}>
<Icon name={'edit'} size={25} color="#000" />
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
);
};
I think creating an array of ref will help you to resolve.
Try this way
const ListComponent = ({list}) => {
const textInputValue = useRef('');
const textInputRef = useRef(null);
changeItemName = (text) => {
textInputValue.current = text;
};
const collectionRef = useRef(list.map(() => createRef()));
return (
<ScrollView>
{list.length > 0 &&
list.map((item, index) => (
<View key={item._id}>
<TouchableOpacity>
<View
<Text>{`Item: `}</Text>
<TextInput ref={collectionRef.current[index]} onChangeText={changeItemName}>
{item.name}
</TextInput>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
textInputValue.current = '';
}}>
<Icon name={'check'} size={25} color="#000" />
</TouchableOpacity>
<View>
<TouchableOpacity
onPress={() => {
textInputValue.current = item.name;
collectionRef[index].current.focus();
}}>
<Icon name={'edit'} size={25} color="#000" />
</TouchableOpacity>
</View>
</View>
))}
</ScrollView>
);
};

Categories

Resources