react-hook-form useFieldArray with React-Native - react-native

Is it possible to use ReactNative with useFieldArray from react-hook-form? I couldn't find any reference for that.
I'm trying to use it but I can't get the output data from the TextInputs. It looks like the onChange is not working, I tried to use the onChange prop but still couldn't make it.
Example:
const {
control,
formState: {errors},
register,
getValues,
handleSubmit,
} = useForm({
defaultValues: {
playerNameInput: [{playerName: ''}, {playerName: ''}],
},
});
const {fields, append, remove} = useFieldArray({
control,
name: 'playerNameInput',
});
return(
<>
{fields.map((player, index) => (
<View>
<Controller
control={control}
rules={{required: true}}
name="playerNameInput"
render={() => (
<TextInput
style={{width: 100}}
defaultValue={`${player.playerName}`}
{...register(`playerNameInput.${index}.playerName`)}
/>
)}
/>
</View>)}
<Button onPress={handleSubmit(data => console.log(data))}>
Save Changes
</Button>
</>
)

Related

Is there a way to set a state with textinput when onChangeText is already in use?

Im trying to set a state with the values from a textinput (which is a reusable component), Im using onChangeText to setFieldValue (useFormikContext()), I also want to set a state which will be sending to the Parent component. I tried using onChange but noticed it saves the text without the last word/number, for instance if I type 0123456789, the setFieldValue gets 0123456789, but the other one (with onChange) gets only 012345678 (without 9).
Here is the code:
function AppFormField({ name, width, childToParent, ...otherProps }) {
const { setFieldTouched, setFieldValue, errors, touched, values } =
useFormikContext();
return (
<>
<TextInput
onBlur={() => setFieldTouched(name)}
onChangeText={(text) => setFieldValue(name, text)}
onChange={() => childToParent(bn)}
value={values[name]}
width={width}
{...otherProps}
/>
<ErrorMessage error={errors[name]} visible={touched[name]} />
</>
);
}
Parent Component:
...
const [bn, setBN] = useState("");
const childToParent = (childdata) => {
setBN(childdata);
console.log(childdata);
};
console.log("bn");
console.log(bn);
...
return (
...
<UppFormField
keyboardType="numeric"
autoCorrect={false}
// icon="bank"
name="acct_number"
placeholder="Account Number"
style={{ paddingRight: 50 }}
childToParent={childToParent}
/>
...
)
Make a middle function called
const onTextChange = (text) => {
setFieldValue(text)
parentFunction(text)
}
then TextInput takes has
onChangeText={onTextChange}

Strange behavior using useState to load data into a object state

i have broken my head trying to understand a problem with my code. I'm new with React Native so there may be a standard behavior that i am unaware of. This is my problem:
In my component i have a useEffect() to load my data like "componentDidMount":
useEffect( () => {
async function loadDadosLista(){
let listaRecebida = await getListaByID(route.params.idLista);
setLista(listaRecebida);
};
loadDadosLista();
}, []);
My function works correctly, the function getListaById accesses my realm.db and return my object lista. After that I can access the data and associate it with components of type TextInput. My real problem is that any change the i do in any component using properties of lista, overwrites all data leaving only the one that has been modified. I'm using spread operator but apparently it doesn't work. Below is my complete code for better understanding.
function ListConfig(){
const [lista, setLista] = useState({});
useEffect( () => {
async function loadDadosLista(){
let listaRecebida = await getListaByID(route.params.idLista);
setLista(listaRecebida);
};
loadDadosLista();
}, []);
return(
<View style={styles.container}>
<View style={[styles.containerLinha, styles.linha2]}>
<View style={styles.inputLocal}>
<TextInput
name='estabelecimento'
placeholder='Venda do seu Francisco'
placeholderTextColor={theme.colors.cinzaPrimario}
style={styles.textInputLocal(theme)}
value={lista.estabelecimento}
maxLength={25}
onChangeText={ (value) => {
setLista({
...lista,
estabelecimento: value
})
}}
textAlignVertical='bottom'
/>
<IconLocation width={20} height={24} />
</View>
</View>
<View style={styles.containerNotif}>
<Text style={styles.textoNotif(theme)}>
Me notifique 20 minutos antes
</Text>
<ToggleSwitch
isOn={lista.notificacaoAtiva}
onColor={theme.colors.cinzaSecundario}
offColor={theme.colors.cinzaSecundario}
thumbOnStyle={{
backgroundColor: theme.colors.destaque
}}
size="medium"
onToggle={(isOn) => {
setLista({
...lista,
notificacaoAtiva: isOn
});
}}
/>
</View>
</View>
);
}
export default ListConfig;
My object lista have this properties:
{
estabelecimento: 'nameOfEstabelecimento',
notificacaoAtiva: true
}

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 })}
/>

How to add comments to get stream in react native

I want to add a comment section to my react native app similar to instagram's one. I am using a getstream activity feed and have tried importing CommentField from react-native-activity-feed but i get an invariant violation error when i use it. However, i'm not fully convinced the CommentField will get me the type of comment section I want. Does getstream support this or will I need to make my own comment field and save it in a database?
EDIT:
I have this Activity:
const CustomActivity = (props) => {
return (
<Activity
{...props}
Footer={
<>
<CommentList
CommentItem={({ comment }) => ( <CommentItem comment={comment} /> )}
activityId={props.activity.id}
reactions={props.activity.latest_reactions}
/>
<Image source={ require('./images/logo.png') } style={{width:98, height:22}}/>
<LikeButton {...props} />
<CommentBox
onSubmit={(text) =>
props.onAddReaction('comment', CustomActivity, { text: text })
}
styles={{ container: { height: 78 } }}
/>
</>
}
/>
);
};
Then this gets rendered:
<FlatFeed
feedGroup = "timeline"
userID = User ID is put here
Activity={CustomActivity}
notify/>
I currently get this error when I submit a comment: Errors for fields 'activity_id', 'parent'
I think it may have something to do with activityId in the CommentList but im not too sure
You'll want to use the CommentBox and CommentList components. We do something like this in our example app:
<SinglePost
activity={activity}
feedGroup={feedGroup}
userId={userId}
Activity={(props) => (
<React.Fragment>
<Activity
{...props}
/>
<CommentList
CommentItem={({ comment }) => ( <CommentItem comment={comment} /> )}
activityId={props.activity.id}
reactions={props.activity.latest_reactions} />
</React.Fragment>
)}
Footer={(props) => {
return (
<CommentBox
onSubmit={(text) =>
props.onAddReaction('comment', activity, { text: text })
}
avatarProps={{
source: (userData) =>
userData.data.profileImage,
}}
styles={{ container: { height: 78 } }}
/>
);
}}
/>

I am using react-native-swiper-flatlist , but I cannot figure it out how to use scrollToIndex on button press

I am using react-native-swiper-flatlist , I want to scroll forward to some index by tapping button but no clue how to do it. Although I am very beginner to react native development.
I have searched alot but nothing helps, I get an error of undefined is not an object this2.swiper.scrollToIndex'
render() {
return (
<View style={styles.container}>
<SwiperFlatList
ref={swiper => {
this.swiper = swiper;
}}
data={[
{ key: "a" },
{ key: "b" },
{ key: "c" },
{ key: "d" },
{ key: "e" }
]}
index={0}
renderItem={({ item, index }) => (
<View>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Image
style={styles.child}
source={require("../../assets/advertisementtwo.png")}
/>
<Button
title={"Next"}
onPress={this.swiper.scrollToIndex(1, true)}
style={{ backgroundColor: "white" }}
/>
</View>
)}
/>
</View>
);
}
Should swipe on button click
Here is the screenshot of the error I am getting
Try adding ref='swiper' as a SwiperFlatList prop,
Example
<SwiperFlatList ref='swiper'/>
this.refs.swiper._scrollToIndex(2)
For those who are using React hook instead of class, you can do sth like that to utilise the scrollToIndex function
//First, make a ref for storing the swiper instance inside your swiper compoent
const swiperRef = useRef<any>({});
//Second, store the reference
<SwiperFlatList
ref={(component) => { swiperRef.current._swiper = component; }}
>
//Later on, you can call the function like this
swiperRef.current._swiper.scrollToIndex({index: 2})