React native collapsible malformed calls from JS: field sizes are different - react-native

I'm using oblador/react-native-collapsible
and when I try to toggle the collapsible component I get a warning message Malformed calls from JS: field sizes are different.
Here is my code:
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
this.state = {
isCollapsed: true
};
}
toggle() {
this.setState({ isCollapsed: !this.state.isCollapsed });
}
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<TouchableOpacity onPress={this.toggle}>
<Icon
active
type="FontAwesome"
name="caret-down"
/>
</TouchableOpacity>
<Collapsible collapsed={this.state.isCollapsed}>
<View>
<Text>Hello World!</Text>
</View>
</Collapsible>
</SafeAreaView>
);
}
I followed the example code here
Can anyone help me solve this? Thank you!

Related

How can I hide/show components by touching not button but screen on React Native?

I'm learning React Native for the first time. I want to implement a function to show/hide the component by touching the screen, not a specific button.
(Please check the attached file for the example image.)
enter image description here
In this code, I've tried to make a function. if I touch the screen (<View style={style.center}>, then show/hide the renderChatGroup() and renderListMessages() included in <View style={style.footer}>. The source code is below.
In my code, it works. However, the two <View> tag is not parallel. the footer view is center View's child.
I want to make them parallel. but I couldn't find the contents about controlling another <View> tag, not a child. In this code, I used setState, then I couldn't control another the below <View>.
Of course, I tried Fragment tag, but it didn't render anything.
How could I do implement this function? Please help me!
export default class Streamer extends React.Component {
constructor(props) {
super(props);
this.state = {
isVisibleFooter: true,
};
}
renderChatGroup = () => {
const { isVisibleFooter } = this.state;
if (isVisibleFooter) {
return (
<ChatInputGroup
onPressHeart={this.onPressHeart}
onPressSend={this.onPressSend}
onFocus={this.onFocusChatGroup}
onEndEditing={this.onEndEditing}
/>
);
}
return null;
};
onPressVisible = () => {
const { isVisibleFooter } = this.state;
this.setState(() => ({ isVisibleFooter: !isVisibleFooter }));
};
render() {
return (
<SafeAreaView style={styles.container}>
<SafeAreaView style={styles.contentWrapper}>
<View style={styles.header} />
<TouchableWithoutFeedback onPress={this.onPressVisible}>
<View style={styles.center}>
<View style={styles.footer}>
{this.renderChatGroup()}
{this.renderListMessages()}
</View>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
</SafeAreaView>
);
}
}
Firstly I would highly recommend you use react native with functional components and React Hooks as they alternative will soon will be deprecated.
Since onPress is not available on the View Component, you would need to replace it with TouchableWithoutFeedback as you have already done in your code.
For Showing/Hiding a view you would need to use a conditional operator.
export default class Streamer extends React.Component {
constructor(props) {
super(props);
this.state = {
isVisibleFooter: true,
};
}
renderChatGroup = () => {
const { isVisibleFooter } = this.state;
if (isVisibleFooter) {
return (
<ChatInputGroup
onPressHeart={this.onPressHeart}
onPressSend={this.onPressSend}
onFocus={this.onFocusChatGroup}
onEndEditing={this.onEndEditing}
/>
);
}
return null;
};
onPressVisible = () => {
this.setState(() => ({ isVisibleFooter: !isVisibleFooter }));
const { isVisibleFooter } = this.state;
};
render() {
return (
<SafeAreaView style={styles.container}>
<SafeAreaView style={styles.contentWrapper}>
<View style={styles.header} />
<TouchableWithoutFeedback onPress={this.onPressVisible}>
<View style={styles.center}>
{isVisibleFooter && <View style={styles.footer}>
{this.renderChatGroup()}
{this.renderListMessages()}
</View>}
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
</SafeAreaView>
);
}
}
Here you can see i have replaced
<View style={styles.footer}>
{this.renderChatGroup()}
{this.renderListMessages()}
</View>
with
{isFooterVisible && <View style={styles.footer}>
{this.renderChatGroup()}
{this.renderListMessages()}
</View>}
stating that to only display the Footer View when
const isFooterVisible = true;

Implement onPress on Flatlist item

I am trying to send the data of the flatlist items when clicked and set to another class.The ontouch is working but I am having the error below in the image. Also how can I send the data of api to the other class and get from another class? I have implemented as follows:
export default class FlatSpeakers extends Component {
constructor(props) {
super(props);
this.state = { isLoading: true, data: [],selectedItem: null, }
const { navigate } = this.props.navigation;
}
onPressItem = () => {
navigate('SpeakersClick')
};
componentDidMount() {
axios.get('https://rallycoding.herokuapp.com/api/music_albums')
.then(res => {
this.setState({
isLoading: false,
data: res.data,
})
})
}
renderItem({ item }) {
return (
<TouchableOpacity onPress={()=>this.onPressItem(item)} >
<Card>
<CardSection>
<View style={styles.thumbnailContainerStyle}>
<Image
style={styles.thumbnailStyle}
source={{ uri: item.image }}
/>
</View>
<View style={styles.headerContentStyle}>
<Text style={styles.headerTextStyle}>{item.title}</Text>
<Text>{item.artist}</Text>
</View>
</CardSection>
</Card>
</TouchableOpacity>
)
}
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, padding: 20 }}>
<ActivityIndicator />
</View>
)
}
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={this.renderItem}
keyExtractor={(item, index) => index}
onPress={this.onPressItem}
/>
</View>
);
}
}
Problem in your code is, that you are calling same method from two sides - on one side you are passing arguments in it on another side you are not passing arguments. If you wan't to have both cases covered you should change you onPressFunction, to accept arguments - in your case item:
onPressItem = (item) => {
navigate('SpeakersClick')
};
try to put this.onPressItem = this.onPressItem.bind(this) on constructor(props)

Change TextInput editable attribute when I press a button (Not working)

I am trying to change editable with state with the click of a button, but it is not working for some reason. I have seen other people do it this way and it works. Is there another way to do this instead? or am i missing something? Thanks
`class Settings extends Component {
constructor(props) {
super(props);
this.state = {
editable: false,
name: '',
};
this.handleEdit = this.handleEdit.bind(this);
this.handleName = this.handleName.bind(this);
}
handleEdit() {
this.setState({
editable: !this.state.editable,
});
}
handleName = (text) => {
this.setState({
name: text,
});
};
render() {
return(
<View style={styles.container}>
<View style={styles.headerContainer}>
<Text style={styles.header}>Settings</Text>
</View>
<View style={styles.section}>
<View style={styles.sectionTitleContainer}>
<Text style={styles.sectionTitle}>My Account</Text>
</View>
<View>
<Text>Name:</Text>
<TextInput
placeholder="name"
value={this.state.name}
onChangeText={this.handleName}
editable={this.state.editable}
/>
</View>
<View>
<TouchableOpacity onPress={() => this.handleEdit}>
<Text>Edit</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
export default Settings;`
Change your
<TouchableOpacity onPress={() => this.handleEdit}>
To
<TouchableOpacity onPress={this.handleEdit}>
I believe that since you already binded 'this' to the handleEdit function you dont need to pass the () => anymore.

undefined not an object ->react native JS

my Code is:
import Note from './Note';
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
noteArray: [],
noteText: '',
}
}
render() {
let notes = this.state.noteArray.map((val, key)=>{
return <Note key={key} keyval={key} val={val}
deleteMethod={()=>this.deleteNote(key)}></Note>
});
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>Yapılacaklar Listesi</Text>
</View>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<View style={styles.footer}>
<TextInput
style={styles.textInput}
placeholder='Notunuz...'
placeholderTextColor='white'
underlineColorAndroid='transparent'
onChangeText={(noteText)=> this.setState({noteText})}
value={this.state.noteText}>
</TextInput>
</View>
<TouchableOpacity onPress={ this.addNote.bind(this) } style={styles.addButton} >
<Text style={styles.addButtonText}>+</Text>
</TouchableOpacity>
</View>
);
}
addNote()
{
if (this.state.noteText){
var d=new Date;
this.state.noteArray.push({
'date':d.getFullYear()
+'/'+(d.getMonth()+1)
+'/'+d.getDate()
});
this.setState({ noteArray: this.state.NoteArray })
this.setState({ noteText: '' })
}
}
}
My error is:undefined not an object (evaluating 'this.state.noteArray.map')
how can i solve this?
i started learn react. The error's screen is
Error Screen
it's my first example. :)
You have to make sure your array is existent:
let notes = !!this.state.noteArray && this.state.noteArray.map((val, key)=>{
should do the job.
The !! is a double negation to avoid another typical error.
This way if noteArray doesn´t exist, the second part after the && is not executed. You could go further and add security checks like checking that it actually is an array etc. but with the above line it should work as long as you actually have an array.

state property undefined in render function

In the render function on one of my views I am trying to have the opacity of a view be tied to a state property: this.state.infoOpacity.
This is turning an error "undefined is not an object (evaluating 'this.state.infoOpacity')"
Any guidance would be helpful.
export default class BookView extends Component
{
constructor(props) {
super(props);
this.state = {
hideInfo:false,
infoOpacity:0.80,
swiperWidth:Dimensions.get('window').width,
swiperHeight:Dimensions.get('window').height
};
}
render() {
pages.forEach(function(ranPage){
photoViews.push(
<View key={ranPage.letter} style={{width: Dimensions.get('window').width, height: Dimensions.get('window').height}}>
<View style={[styles.meow,{opacity: this.state.infoOpacity}]}>
<Text style={styles.text}>{ranPage.name}</Text>
<Text style={styles.text}>{ranPage.phonetic}</Text>
<Text style={styles.text2}>{ranPage.description}</Text>
</View>
</View>
)
});
return (
<View style={{flex:1}}>
<Swiper showsButtons={false} style={{backgroundColor:'#000'}} width={this.state.swiperWidth} height={this.state.swiperHeight}>
{photoViews}
</Swiper>
</View>
);
}
}
The context changed in your forEach function. Use an arrow function to fix your issue. So instead of
pages.forEach(function(ranPage){ ... });
write this
pages.forEach((ranPage) => { ... });