I am facing two problems & can not resolve this. Can anyone explain why this is happening? Or can anyone give me the solution?
Problem NO 1:
There are two components 1) Home 2) Inner
In the Home there are list of data & when I click any one of them it route to Inner. There are also a back button with using navigator pop. There is the issue sometime reproduce - When I click on back, it routes to Home but there is no data(listview element) but when I touch on the screen the data shows properly.
Problem NO 2:
In the home component within the list data, there also some repeated data within the single row.
I have used map function for this. Sometimes ( Most of the time it shows correctly ) it is also not shown in list view, the row is showing properly but the repeated data are missing.
<ListView onEndReached={this.props.reloadArticles} onEndReachedThreshold={10} dataSource={this.props.dataSource} renderRow={this.renderPost} enableEmptySections={true} refreshControl={ <RefreshControl refreshing={this.props.isRefreshing} onRefresh={this.props._onRefresh} /> } />
NO 1:
Sounds like this: https://github.com/facebook/react-native/issues/8607
If you use rn 0.4.0 setting initialListSize={0} could help
NO 2:
Could you please post your renderRow / dataSource code
#SnowMax Sorry for late reply & thanks for help.
Due to confedential project I could not share all code but I can share u the code structure:
renderPost = (list, sectionID, rowID) => {
if(list && list.is_shared_post == true){
return (
<WallShared list={list} rowID={rowID} />
);
}
}
class WallShared extends Component {
constructor(props) {
super(props);
}
render() {
if( this.props.list.is_shared_post == true){
switch(this.props.list.TblPostsComments.post_type){
case 'T':
return (<ShareText list={this.props.list} />);
default:
return (<ShareDefault list={this.props.list} rowID={this.props.rowID} />);
break;
}
} else {
return (
<View>something</View>
)
}
}
}
export default WallShared;
class ShareText extends Component {
constructor(props) {
super(props);
this.state ={
isLoggedIn:false,
}
}
componentDidMount(){
}
render() {
var ShareBlock = this.props.list.TblPostsComments.shared_contents.map(function(cont, ind) {
return (
<View style={[styles.feedItem, styles.SfeedItem]} key={ind}> </View>
);
},this);
return(
<View style={styles.feedItem}>
<View style={styles.sharedWrap}>
{ ShareBlock }
</View>
</View>
);
}
}
export default ShareText;
Related
I'm having an issue with React-native where I have a component TouchTimer which uses an AnimatedTimer component. This timer is supposed to start and stop when it is tapped, which it does, however all of the TouchTimer components I add to a page will start and stop whenever any of them are tapped, rather than only affecting the tapped component.
Below is a snippet of my component:
TouchTimer.tsx
export class TouchTimer extends React.Component<TouchTimerProps> {
state: {
...
paused: boolean,
}
constructor(props) {
super(props);
...
this.state = {
...
paused: true,
}
}
startStop() {
this.setState({paused: !this.state.paused});
}
render() {
const { time } = this.props;
return (
<TouchableHighlight onPress={() => this.startStop()}>
<View>
<AnimatedTimer
...
time={time}
pause={this.state.paused}
/>
<View style={styles.timeContainer}>
<Text style={styles.time}>{this.state.remaining}</Text>
</View>
</View>
</TouchableHighlight>
)
}
}
And here is a snippet of the screen containing these components:
Details.tsx
import { TouchTimer } from '../components/TouchTimer';
...
export class RecipeDetailsScreen extends React.Component<NavigationInjectedProps> {
...
{this.state.steps.map(step => (
<List.Item
key={step.id}
title={"Step " + step.index}
style={styles.step}
description={step.short_desc}
right={() => (step.time > 0 &&
<TouchTimer
time={step.time * 60000}
/>
)}
/>
)
}
I have tried wrapping the TouchTimer components in a View and changing the paused boolean to a prop, to no avail.
I have also tested to see if this issue appears when the components are not siblings, and when they are not produced as the result of a callback, and the issue still persists in both these cases.
If anybody has any advice or answers on how to make these timers independent I would very much appreciate it!
Curiously that component seems to be implemented with a global pauseFlag that applies to all component instances. See https://github.com/dalisalvador/react-native-animated-timer/blob/master/src/Components/AnimatedTimer.js#L34
So I don't think you're doing anything wrong here, this is a limitation of the library code that is coupling all instances of your timer to the same pauseFlag value.
I am scratching my head hard; trying to figure out what's wrong in below snippet.
import React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
class MyButton extends React.Component {
setNativeProps = (nativeProps) => {
alert(JSON.stringify(this._root.props)) //able to get this.v here
}
render() {
return (
<View ref={cc => {this._root = cc; this.v = 100 }} me="tom">
<Text ref={component => { this._root1 = component;}} style={{margin:55}} onPress={()=>this.setNativeProps({text:'fgfg'})}>{this.props.label} </Text>
</View>
)
}
}
export default class App extends React.Component {
render() {
return (
<TouchableOpacity >
<MyButton label="Press me!" />
</TouchableOpacity>
)
}
}
basically trying to get the props from <View> element i.e. this._root.props using ref callback
though this._root1.props works perfectly fine all the times.
could someone help me figure out what's the problem with it?
EDIT:
I am even able to see this._root but even not this._root.props.me.
Could you try not to do
alert(JSON.stringify(this._root.props))
instead just do
alert(this._root.props)
i.e. remove JSON.stringify
The reason it's not working is because View is having a child element with-in itself while with using Text it's not having any child in it.
I'm trying to call a function that will fire upon onFoucs on TextInput that will scroll the scrollView all the way down (using scrollToEnd())
so this is my class component
class MyCMP extends Component {
constructor(props) {
super(props);
this.onInputFocus = this.onInputFocus.bind(this);
}
onInputFocus() {
setTimeout(() => {
this.refs.scroll.scrollToEnd();
console.log('done scrolling');
}, 1);
}
render() {
return (
<View>
<ScrollView ref="scroll">
{ /* items */ }
</ScrollView>
<TextInput onFocus={this.onInputFocus} />
</View>
);
}
}
export default MyCMP;
the component above works and it does scroll but it takes a lot of time ... I'm using setTimeout because without it its just going down the screen without calculating the keybaord's height so it not scrolling down enough, even when I keep typing (and triggering that focus on the input) it still doesn't scroll all the way down.
I'm dealing with it some good hours now, I did set the windowSoftInputMode to adjustResize and I did went through some modules like react-native-keyboard-aware-scroll-view or react-native-auto-scroll but none of them really does the work as I need it.
any direction how to make it done the right way would be really appreciated. thanks!
Rather than using a setTimeout you use Keyboard API of react-native. You add an event listener for keyboard show and then scroll the view to end. You might need to create some logic on which input is focused if you have more than one input in your component but if you only have one you can just do it like the example below.
Another good thing to do is changing your refs to functional ones since string refs are considered as legacy and will be removed in future releases of react. More info here.
class MyCMP extends Component {
constructor(props) {
super(props);
this.scroll = null;
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
}
componentWillUnmount () {
this.keyboardDidShowListener.remove();
}
_keyboardDidShow() {
this.scroll.scrollToEnd();
}
render() {
return (
<View>
<ScrollView ref={(scroll) => {this.scroll = scroll;}}>
{ /* items */ }
</ScrollView>
<TextInput />
</View>
);
}
}
export default MyCMP;
If you have a large dataset React Native docs is telling you to go with FlatList.
To get it to scroll to bottom this is what worked for me
<FlatList
ref={ref => (this.scrollView = ref)}
onContentSizeChange={() => {
this.scrollView.scrollToEnd({ animated: true, index: -1 }, 200);
}}
/>
I have a component in React Native which updates it's state once it knows what size it is.
Example:
class MyComponent extends Component {
...
render() {
...
return (
<View onLayout={this.onLayout.bind(this)}>
<Image source={this.state.imageSource} />
</View>
);
}
onLayout(event) {
...
this.setState({
imageSource: newImageSource
});
}
...
}
This gives the following error:
Warning: setState(...): Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount.
I guess the onLayout function is called while still rendering (which can be good, the sooner the update, the better). What is the correct way to solve this problem?
Thanks in advance!
We got around this by using the measure function, you will have to wait until the scene is fully complete before measuring to prevent incorrect values (i.e. in componentDidMount/componentDidUpdate). Here's an example:
measureComponent = () => {
if (this.refs.exampleRef) {
this.refs.exampleRef.measure(this._logLargestSize);
}
}
_logLargestSize = (ox, oy, width, height, px, py) => {
if (height > this.state.measureState) {
this.setState({measureState:height});
}
}
render() {
return (
<View ref = 'exampleRef' style = {{minHeight: this.props.minFeedbackSize}}/>
);
}
Here is a solution from documentation for such cases
class MyComponent extends Component {
...
render() {
...
return (
<View>
<Image ref="image" source={this.state.imageSource} />
</View>
);
}
componentDidMount() {
//Now you can get your component from this.refs.image
}
...
}
But for my opinion it's better to do such things onload
I've trying to set up a change event if someone modifies a switch component. The approach is to design a view that contains multiple switches and allows the user to set the state per each notification that will end up in a POST api-call. Futher, I'd like to load the initial values from a api-call.
How can I access the state (weather it's checked / unchecked) in my onChangeFunction? And how can I get an element using their ID or name? (same as in HTML/CSS with #mySwitch.setValue(true)?
Given code:
class Settings extends Component {
onChangeFunction(type, props) {
Alert.alert("changed", "==> " + props.state)
}
render() {
return (
<View style={styles.container}>
<Switch onValueChange={this.onChangeFunction.bind(this, "TASK_CREATED", this.props)} value={this.state} />
</View>
);
}
}
You have a mess there between the propsand the state concept. You can do:
class Settings extends Component {
state = {
taskCreated: false,
};
onChangeFunction(newState) {
this.setState(newState, () => Alert.alert("Changed", "==> " + this.state));
}
render() {
return (
<View style={styles.container}>
<Switch onValueChange={(value) => this.onChangeFunction({taskCreated: value})}
value={this.state.taskCreated}
/>
</View>
);
}
}
Notice that this.setState is asynchronous so you can safely read its value using the callback that the method provides.