Nativebase Picker Item not showing Selected value - react-native

I am trying to select item from picker item. problem is when i clicked on item then on function handler onValueChangeJob(value) perform some task
onValueChangeJob(value) {
this.setState({ jobValue: value.jobTitle})
USE value.number form another task
});
}
Below is my picker component
<Picker
style={commonStyle.pickerStyle}
textStyle={commonStyle.textStylePicker}
headerTitleStyle={commonStyle.headerTitleStyle}
headerBackButtonTextStyle={commonStyle.headerBackButtonTextStyle}
iosIcon={<Icon name="ios-arrow-down" />}
mode="dropdown"
placeholder="MAKE A SELECTION"
placeholderStyle={commonStyle.placeholderStyle}
note={false}
itemTextStyle={commonStyle.itemTextStyle}
selectedValue={this.state.jobValue}
onValueChange={this.onValueChangeJob.bind(this)}
>
{jobItems}
</Picker>
While The jobitems coming from map which created in render() function like
jobItems = this.state.jobTypesList.map((v,i) => {
return <Picker.Item key={i} value={v} label={v.jobTitle} />
});
So here if I used directly in picker.item props value-{v.jobTitle} then selected value change but i want to use whole object v in onValueChangeJob(value) function. One main thing state update but cant displaying on selected value of picker
tried lots of different things but not happening the thing what i want.
how should i handle this with proper example as i am new in react native.
Look at how my picker looks in this image

After lots of googling on one solution i find that solution that i have to filter this.state.jobTypesList this array on onValueChange handler and grab objects of particular job Title
return this.state.jobTypesList.map((v,i) => {
return <Picker.Item key={i} value={v.jobTitle} label={v.jobTitle}
});
let filterArray = this.state.jobTypesList.filter((v) => v.jobTitle === value)[0]
filterArray.jobTitle
filterArray.jobNumber

If you are using yup schema and validations, then you can use getValues() in selectedValue property.
I resolved it by
<Picker
selectedValue = {getValues('storeId')}
onValueChange={itemValue =>
setValue('storeId', itemValue, true)
}>
.../>

Related

How to dinamically update the value coming from useAnimatedStyle - Reanimated 2

Say that I have a component where I create child components based on the number of elements passed from the parent ( think of it as a page indicator, for example ).
What I would like to do, is to animate the transition between these dots (their backgroundColor) depending on which one is active.
I have tried in a few ways to match the current value to the index of the child element, however, since I don't have the index beforehand, my attemps have failed.
I am posting the basic component down there without my fail attemps to animate it so it illustrates better what I am talking about.
How would one go about doing that in reanimated 2?
const component = ({active, amountOfDots}) => {
const dotsArray = Array(amountOfDots).fill(0);
return (
<View style={{}}>
{dotsArray.map(() => {
return <Animated.View style={{}} />;
})}
</View>
);
};

Does event, onBlur, work with the React Admin useInput hook on custom field?

I have a custom field that takes JSON and dynamically prints out TextField objects.
For each TextField I have an onChange and onBlur event. The onChange is for updating the state and the onBlur is for updating the final value to be past to the API and saved.
I'm using the useInput hook to save the updated value, however, when I use onBlur it doesn't save the value.
If I only use onChange it DOES save the value, but only the first key stroke, which is why I switched to onBlur. Any ideas? Here's the code:
const DefaultField = props => {
const {
input,
} = useInput(props.record);
let parsedObj = JSON.parse(props.record.values);
const [defaultState, setDefaultState] = React.useState({
websiteLink: parsedObj.websiteLink,
menuInstructionsLink: parsedObj.menuInstructionsLink,
surveyLink: parsedObj.surveyLink
});
const handleBlur = (event) => {
parsedObj[event.target.name] = event.target.value;
props.record.values= JSON.stringify(values);
//event.target.value is the expected value but it's not persisted when I save it.
};
const handleChange = (event) => {
setDefaultState({ ...defaultState, [event.target.name]: event.target.value });
};
return (
<FormControl component="fieldset">
<FormGroup {...input} id="defaultGroup" aria-label="position">
<React.Fragment>
{ Object.keys(parsedObj).map((key) => (
<TextField
id="standard-full-width"
name={key}
label={key}
onBlur={handleBlur}
onChange={handleChange}
style={{ margin: 8, width: '500px' }}
value={defaultState[key]}
fullWidth
margin="normal"
/>
))}
</React.Fragment>
</FormGroup>
</FormControl>
)
}
I never solved it properly, but I did discover that the dataProvider was being called twice. The first time it would send the expected values, but the second time the values were set back to the original, however I noticed that the field "previousData" had the values I needed. For now I'm just making sure to use the "previousData" field. This isn't the prettiest solution, but for now it's working. Maybe it's a bug or something sinister is going on.

What is renderRow ()

I went through React-Native docs to figure out what is renderRow() but for some reason I am unable to comprehend what does it say from Facebook React-Native docs
This what the official docs says
renderRow
(rowData, sectionID, rowID, highlightRow) => renderable
Takes a data entry from the data source and its ids and should return a renderable component to be rendered as the row. By default the data is exactly what was put into the data source, but it's also possible to provide custom extractors. ListView can be notified when a row is being highlighted by calling highlightRow(sectionID, rowID). This sets a boolean value of adjacentRowHighlighted in renderSeparator, allowing you to control the separators above and below the highlighted row. The highlighted state of a row can be reset by calling highlightRow(null).
[Question:] Can someone please explain me this with example?
ListView is deprecated, use FlatList instead with the equivalent renderItem method. This is responsible of the actual rendering of each row based on the data records:
const data = [
{ key: '1', label: 'foo' },
{ key: '2', label: 'bar' }
]
renderTheItem = ({item}) => {
return <Text>{item.label}</Text>
}
<FlatList
data={data}
renderItem={this.renderTheItem}
/>
And the rendered result will be something like this:
<View> --> coming from FlatList wrapper
<Text key="1">foo</Text> --> coming from the custom renderTheItem function
<Text key="2">bar</Text>
</View>
It is mandatory to either add a unique key prop for each data record, or define a keyExtractor function. Also important to destruct the item in the renderer function with ({item}) as it has other meta parameters as written in documentation of FlatList.
renderItem({ item, index, separators}) => {}

Using FlatList#onViewableItemsChanged to call a Component function

I'm currently attempting to implement a form of LazyLoading using the FlatList component, which introduces a neat little feature called onViewableItemsChanged which gives you a list of all of the components that are no longer on the screen as well as items that are now on the screen.
This is a custom LazyLoad implementation and as such is more complicated than most LazyLoad open-sourced libraries that are available, which is why I'm working on my own implementation. I'm already looked into react-native-lazy-load and others.
Basically, I need to be able to call a function that's part of the component being rendered in the FlatList, I've tried creating a reference to the item rendered in the FlatList and calling it as such, but it doesn't seem to work.
For example:
<FlatList data={...}
renderItem={(item) => <Example ref={(ref) => this[`swiperRef_${item.key}`] = ref}}
onViewableItemsChanged={this.onViewableItemsChanged}
/>
onViewableItemsChanged = ({viewableItems}) => {
viewableItems.forEach((item) => {
const { isViewable, key } = item;
if(isViewable && !this.cachedKeys.includes(key)) {
const ref = this[`swiperRef_${key}`];
if(!ref) return console.error('Ref not found');
ref.startLoading();
this.cachedKeys.push(key);
}
});
}
Now in the <Example /> component I would have a function called startLoading which should be called when a new visible item is brought onto the screen, however the ref never exists.
I was actually doing everything correctly, but I accidently forgot to deconstruct the parameter returned from the renderItem function, so (item) should have been ({ item })
That's all there was to it.

React Native ListView row not re-rendering after state change

React Native ListView: Rows are not re-rendering after datasource state has changed.
Here is a simplified version of my code:
render(): {
return <ListView
dataSource={this.state.DS}
renderRow={this.renderRow}/>
}
renderRow(item): {
return <TouchableOpacity onPress={() => this.handlePress(item)}>
{this.renderButton(item.prop1)}
</TouchableOpacity>
}
renderButton(prop1): {
if (prop1 == true) {
return <Text> Active </Text>
} else {
return <Text> Inactive </Text>
}
}
handlePress(item): {
**Change the prop1 of *item* in an array (clone of dataSource), then**
this.setState({
DS: this.state.DS.cloneWithRows(arrayFromAbove)
})
}
According to Facebook's example, ListView is supposed to rerender every time data source is changed. Is it because I'm only changing a property of an item in data source? It seems like renderRow function is not re-rendering, but render() function is from datasource change.
Thank you.
react is smart enough to detect changes in dataSource and if the list should be re-rendered. If you want to update listView, create new objects instead of updating the properties of existing objects.
The code would look something like this:
let newArray = this._rows.slice();
newArray[rowID] = {
...this._rows[rowID],
newPropState: true,
};
this._rows = newArray;
let newDataSource = this.ds.cloneWithRows(newArray);
this.setState({
dataSource: newDataSource
});
You can read more about similar issue on Github
First you need to set the datasource in the getInitialState function. Then, change the datasource by calling this.setState({}) and passing in the new datasource. It looks like you may have been on the right track above, but I have set up a working example of changing the ListView datasource here . I hope this helps
https://rnplay.org/apps/r3bzOQ