gifted-chat renderAction prop won't call a function - react-native

I'm trying to make a custom menu to share pictures and location using the renderAction prop in gifted-chat. I can't get it to call a function. renderActions={console.log('hello')} outputs as expected, for some reason functions aren't being called.
I've looked at code examples, and I can't find anything that I'm missing - but obviously I'm missing something.
here's the code. If there's any extra info that would be helpful, please let me know and I'll add it. Still new to stack.
renderActions > console.log() doesn't get called
renderActions() {
console.log('renderActions called');
}
renderAction={console.log()} get's called.
renderActions={this.renderActions} does not get called.
I've tried passing it in every way I can think of:
{() = > this.renderActions()}, {this.renderActions.bind(this)}, {this.renderActions} ... nothing seems to work.
render() {
let bgColor = this.props.route.params.bgColor;
return (
<View style={[styles.bodyContent]}>
<GiftedChat
renderBubble={this.renderBubble.bind(this)}
renderSystemMessage={this.renderSystemMessage.bind(this)}
renderInputToolbar={this.renderInputToolbar.bind(this)}
renderActions={() => this.renderActions()}
messages={this.state.messages}
onSend={(messages) => this.addMessage(messages)}
user={{
_id: this.state.uid,
}}
/>
{Platform.OS === 'android' ? (
<KeyboardAvoidingView behavior="height" />
) : null}
</View>
);
}
Any help would be greatly appreciated. I'm sure I'm missing something obvious, but I'm completely stumped. Thank you!

render action is not supposed to console log, if you see what it returns you will see it returns JSX
import {GiftedChat, InputToolbar} from 'react-native-gifted-chat';
// custom action
const customAction = () => {
return(
<View>
<Text>Custom Action</Text>
</View>
);
}
<GiftedChat
renderInputToolbar={props => {
return (
<InputToolbar
{...props}
containerStyle={styles.chatWithoutBorder}
renderComposer={() => <CustomComposer {...props} />}
renderActions={ <CustomAction /> }
renderSend={() => <CustomSend {...props} />}
/>
);
}}
/>
all these custom components are actually normal components you can create it on your own, all you need is to send props for it
and for the footer below the message box, you will need this renderAccessory as described here in the https://github.com/FaridSafi/react-native-gifted-chat

Thanks to my tutor, I have an answer!
The renderInputToolbar={} prop overwrites renderActions={}. I ended up not using the renderActions prop in the <GiftedChat /> component. Instead passing it as a prop to the <InputToolbar />.
Here's the code:
` <GiftedChat
renderBubble={this.renderBubble.bind(this)}
renderSystemMessage={this.renderSystemMessage.bind(this)}
renderInputToolbar={this.renderInputToolbar.bind(this)}
//renderActions={this.renderActions.bind(this)}
messages={this.state.messages}
onSend={(messages) => this.addMessage(messages)}
user={{
_id: this.state.uid,
}}
/>`
Then the renderInputToolbar method:
renderInputToolbar() {
if (this.state.onlineStatus == false) {
} else {
return <InputToolbar renderActions={this.renderActions} />;
}
}

Related

nothing was returned from render but can't be fixed

I don't know what I did wrong in this function, I thought I had a return but I don't think it's being considered, and when I change the closing brackets or parenthesis it shows an error :/
Can someone help me?
function PopSheet() {
let popupRef = React.createRef()
const sheet =() => {
const onShowPopup =()=> {
popupRef.show()
}
const onClosePopup =()=> {
popupRef.close()
}
return (
<SafeAreaView style ={styles.container}>
<TouchableWithoutFeedback onPress={onShowPopup}>
</TouchableWithoutFeedback>
<BottomPopup
title="Demo Popup"
ref ={(target) => popupRef =target}/>
onTouchOutside={onClosePopup}
</SafeAreaView>
);
}
};
You need to use the render function which is responsible for rendering or display the JSX element into your app.
render() {
return (
<SafeAreaView style={styles.container}>
<TouchableWithoutFeedback
onPress={onShowPopup}></TouchableWithoutFeedback>
<BottomPopup title="Demo Popup" ref={target => (popupRef = target)} />
onTouchOutside={onClosePopup}
</SafeAreaView>
);
}

Passing state via route.params with React Navigation returning undefined

I'm attempting to pass a 'passcode' state as params in my React Native app.
I'm doing this by passing params into a 'navigation.navigate' call.
However, every time I navigate to the next screen, it's returning 'undefined' for 'route.params'.
For reference, here is my component I'm passing data FROM:
const SignUpPasscodeScreen = ({ navigation }) => {
const [passcode, setPasscode] = useState(0)
return (
<View>
<View style={styles.mainView}>
<SubLogo />
<Heading title="Set passcode" />
<SubHeading content="You'll need this anytime you need to access your account." />
<Input inputText={ text => setPasscode(text) } inputValue={passcode} />
</View>
<View style={styles.subView}>
<CtaButton text="Continue" onPressFunction={ () => navigation.navigate({ routeName: 'SignUpLegalName', params: { passcode } } ) } />
</View>
</View>
)
}
And here's the component I'm passing data to, and where the error occurs upon navigation:
const SignUpLegalName = ({ route, navigation }) => {
const { passcode } = route.params
return (
<View>
<View style={styles.mainView}>
<SubLogo />
<Heading title="Tell us your name" />
<SubHeading content="This needs to be the same as what's on your passport, or any other form of recognised ID." />
<Input />
<Input />
</View>
<View style={styles.subView}>
<CtaButton text="Continue" onPressFunction={ () => navigation.navigate('SignUpLink')} />
</View>
</View>
)
}
I've tried two forms of passing the props through:
Passing it in as a second argument
Passing it in as a 'params' object as shown above
Both should work according to the documentation - link here
For reference, this is my route structure:
const switchNavigator = createSwitchNavigator({
loginFlow: createStackNavigator({
SignUpPasscode: SignUpPasscodeScreen,
SignUpLegalName: SignUpLegalName,
})
});
The above structure doesn't say to me that it's a nested structure which therefore requires any additional work to pass it through...
Can someone help? It'd be appreciated as it's giving me a headache!
Have a try with below code in the button press event:
<CtaButton
text="Continue"
onPressFunction={() => navigation.navigate('SignUpLegalName',{ passcode })}
/>

FlatList's renderItem doesn't recognise "this" keyword

So, I recently started making FlatList a recurring thing in the app I'm working on. I am right now working on a screen that gives a list of requests and is updated once one is accepted, which is done by pressing a button. There's a method called getNewRequests I am using to update the requests, but it can't seem to be called by the flatline, as it only returns the error TypeError: _this3 is undefined.
I really need that method to work, because I need to update the state of that screen, and trying to type the whole method there only returns the same error. In that context, this always returns undefined.
render(){
return(
<View style={GenericStyles.styles.genericContainer}>
<Text> REQUEST SCREEN </Text>
<FlatList
data={this.state.requestList}
renderItem={this.renderItem}
keyExtractor={item => item.id}
/>
<Button title="Voltar" color="cyan" onPress={() => this.props.navigation.goBack()}/>
</View>
);
}
renderItem({item}){
return(
<Card
containerStyle={{flex: 1, width: 200}}
title={item.Username}>
<Button color="blue" title="Accept" onPress={() => RequestService.allowRequest(item.id, (response) => {
let rsp = JSON.parse(response);
if(rsp.success){
this.getNewRequests();
}
})}/>
</Card>
);
}
You need to either bind the function in your constructor (or wherever you want) doing:
constructor(props){
super(props)
this.renderItem.bind(this)
}
or use arrow function:
renderItem = ({item}) => {
//your function
}
Doing this will give the function access to the this of the current component.

React Native: Lodash Map

I'm new in react native and I want make data function into view.
my function looks like this
renderTest = () => {
<FlatList
onEndReached={0}
onEndReached={() => this.handleEnd()}
>
{_.map(this.state.leads, (leads, index) => {
return (
<Text key={index}>{leads.full_name}</Text>
)
})}
</FlatList>
}
and my View to pass the value of the function
<View style={{flexDirection: 'row'}}>
{this.renderTest()}
</View>
I don't have any idea what's the problem all I just want is to render the value. I hope could someone help me.
edited
Since you already are in react world you can simply use the Array.map:
renderTest = () => {
<FlatList onEndReached={() => this.handleEnd()}>
{this.state.leads.map((lead, index) => {
return (<Text key={index}>{lead.full_name}</Text>)
})}
</FlatList>
}
As long as this.state.leads is an array.
But bottom line is no lodash is needed here.
As seen by your comment on Akrion's answer, I'm guessing you haven't defined the renderTest function inside the component. Another possibility is that you are using a stateless component in which case you cannot access this
I'm just not sure you can define a FlatList like that one. I mean, I think you're missing the return of the function and you have to pass the property data to FlatList this way:
renderTest = () => {
return (
<FlatList
onEndReached={0}
onEndReached={() => this.handleEnd()}
data={this.state.leads}
renderItem={(lead, index) => <Text key={index}>{lead.full_name}</Text>}
/>
)
}
Let me know if this can solve your issue :)

React Native TextInput does not get focus

I have this simple code of a TextInput that I want it to get focus when it first renders and on submits. However, it does not get focus at all.
render() {
return (
<TextInput
ref={(c) => this._input = c}
style={[styles.item, this.props.style]}
placeholder={"New Skill"}
onChangeText={(text) => {
this.setState({text})
}}
onSubmitEditing={(event) => {
this.props.onSubmitEditing(this.state.text);
this._input.clear();
this._input.focus();
}}
/>
);
}
componentDidMount() {
this._input.focus();
}
So my assumption is true. Try to focus is failed, this._input doesn't contain anything when componentDidMount called, because render function still not called yet and no reference for it.
So the solution for now is delay it a little bit until render function already called.
Thats why wrap the code inside setTimeout function quite helpful. Anyway i admit it, it is a little bit tricky. Would be great if someone find the better way.
componentDidMount() {
setTimeout(() => this._input.focus(), 250);
}
You can use autoFocus property of TextInput and set it to true. It will focus TextInput on componentDidMount automatically.I tested it and it's focusing input on both componentDidMount and onSubmitEditing.
render() {
return (
<TextInput
ref={(c) => this._input = c}
placeholder={"New Skill"}
autoFocus={true}
onChangeText={(text) => {
this.setState({text})
}}
onSubmitEditing={() => {
this.props.onSubmitEditing(this.state.text);
this._input.clear();
this._input.focus();
}}
/>
);
}