React Native - setState from array - react-native

I'm trying create-react-native-app for the first time and I want to change text on varying time intervals. But my code only gives me the last item of the array.
import React from 'react';
import { Text } from 'react-native';
const blinkText = [
{
text: "A",
time: 500,
},
{
text: "B",
time: 1000,
},
{
text: "C",
time: 1000,
},
];
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
this.interval = setInterval(() => {
blinkText.map(value => this.setState(value))
}, this.state.time);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return(
<Text>{this.state.text}</Text>
);
}
}
I know I have my problem at componentDidMount() but I could not think of a way. Please take a look at my code and modify. Thanks.

Try this
componentDidMount(){
blinkText.map(e => {
setTimeout(() => {
this.setState(
prevState => ({
text: [...prevState.text, e]
});
);
}, e.time);
});
}
Note that, this.stat.text is an array, so you should render it inside your render() method by applying map()
Example:
{ this.state.text.map((e, i) => {
return (
<Text key={i}>{e}</Text>
);
})}

Related

React navigation and loading component in react native

Hello I have a react component like which either display a list of items or opens another component which allowes me to select some value. Here is the code
import React, { PureComponent } from "react";
import { Text, View } from "react-native";
import { withNavigationFocus } from "react-navigation-is-focused-hoc";
import { NavigationActions } from "react-navigation";
import { connect } from "react-redux";
import ClassListing from '../../components/ClassListing/ClassListing';
import Actions from "../../state/Actions";
import { default as stackStyles } from "./styles";
import {
StyleCreator
} from "../../utils";
let styles = StyleCreator(stackStyles.IndexStyles)();
#withNavigationFocus
#connect(() => mapStateToProps, () => mapDispatchToProps)
export default class ClassList extends PureComponent {
static navigationOptions = ({ navigation }) => {
const { params } = navigation.state;
return {
header: null,
tabBarOnPress({ jumpToIndex, scene }) {
params.onTabFocus();
jumpToIndex(scene.index);
},
};
};
constructor(props) {
super(props);
this.state = {};
console.ignoredYellowBox = ["Warning: In next release", "FlatList"];
}
componentDidMount() {
console.log("componentDidMount");
this.props.navigation.setParams({
onTabFocus: this.handleTabFocus
});
}
componentDidUpdate() {
console.log("I am updated");
}
_handleNavigationBar = () => (
<View style={styles.headerContainer}>
<Text style={styles.headerLeftTitle}>Klasselister</Text>
</View>
);
handleTabFocus = () => {
this.props.resetClassList();
// setTimeout(() => {
// this._openChildSchoolSelector();
// },500);
};
_openChildSchoolSelector = () => {
if (
!this.props.childrenSelection.selectedDependant ||
!this.props.childrenSelection.selectedSchool
) {
console.log("navigate to child selector");
this.props.navigation.dispatch(
NavigationActions.navigate({
routeName: "ChildSchoolSelector",
})
);
}
};
render() {
return (
<View>
{this._handleNavigationBar()}
{this.props.classList &&
this.props.classList.classList &&
this.props.classList.classList.length > 0 ? (
<ClassListing list={this.props.classList.classList} />
) : (
null
// this._openChildSchoolSelector()
)}
</View>
);
}
}
const mapStateToProps = (state) => {
const { classList, childrenSelection } = state.appData;
console.log("[Classlist] mapStateToProps", classList);
console.log("[Classlist] mapStateToProps", childrenSelection);
return {
classList,
childrenSelection
};
};
const mapDispatchToProps = (dispatch) => ({
resetClassList: () => {
dispatch(Actions.resetClassList());
},
});
My issue is that when I come to this tab, I want to reset the list which came from server and then open the school selector again, which I am doing in handleTabFocus. But there I have to first call
this.props.resetClassList();
this._openChildSchoolSelector()
The issue is that this._openChildSchoolSelector() is called while this.props.resetClassList() hasn't fininshed.
this.props.resetClassList() works like this
it calls an action like this
static resetClassList() {
return {
type: ActionTypes.RESET_CLASS_LIST
};
}
which then cleans the classlist like this
case ActionTypes.RESET_CLASS_LIST:
return createDefaultState();
in ClassListReducer.js
and also in ChildrenSelectionRedcuer.js
case ActionTypes.RESET_CLASS_LIST:
return createDefaultState();
Any hints to solve this? My project uses very old React navigation v1
One thing which I did was to use this
componentWillReceiveProps(nextProps) {
console.log(this.props);
console.log(nextProps);
if (
nextProps.isFocused &&
nextProps.focusedRouteKey == "ClassList" &&
(!nextProps.childrenSelection.selectedDependant ||
!nextProps.childrenSelection.selectedSchool)
) {
console.log("componentWillReceiveProps");
this._openChildSchoolSelector();
}
if (
this.props.isFocused &&
this.props.focusedRouteKey === "ClassList" &&
nextProps.focusedRouteKey !== "ClassList"
) {
console.log("reset");
this.props.resetClassList();
}
}
But not sure if this is an elegant way of doing this

react native setInterval cannot read property apply

I am new in react native I am trying to render the count of unread notification for that I called my API in HOC it is working fine for initial few seconds but after that, I started to get the below error
func.apply is not a function
below is my code
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Modal, View } from "react-native";
import { themes } from "./constants";
import { AsyncStorage } from "react-native";
export default (OriginalComponent, animationType) =>
class extends Component {
static propTypes = {
handleFail: PropTypes.func,
theme: PropTypes.string,
visible: PropTypes.bool
};
state = {
modalVisible: true
};
static getDerivedStateFromProps({ visible }) {
if (typeof visible === "undefined") {
setInterval(
AsyncStorage.getItem("loginJWT").then(result => {
if (result !== null) {
result = JSON.parse(result);
fetch(serverUrl + "/api/getUnreadNotificationsCount", {
method: "GET",
headers: {
Authorization: "Bearer " + result.data.jwt
}
})
.then(e => e.json())
.then(function(response) {
if (response.status === "1") {
if (response.msg > 0) {
AsyncStorage.setItem(
"unreadNotification",
JSON.stringify(response.msg)
);
} else {
AsyncStorage.setItem("unreadNotification", 0);
}
}
})
.catch(error => {
alert(error);
// console.error(error, "ERRRRRORRR");
});
} else {
AsyncStorage.setItem("unreadNotification", 0);
}
}),
5000
);
return null;
}
return { modalVisible: visible };
}
handleOpenModal = () => {
this.setState({ modalVisible: true });
};
handleCloseModal = () => {
const { handleFail } = this.props;
this.setState({ modalVisible: false }, handleFail);
};
render() {
const { modalVisible } = this.state;
const { theme } = this.props;
return (
<View>
<Modal
animationType={animationType ? animationType : "fade"}
transparent={true}
visible={modalVisible}
onRequestClose={this.handleCloseModal}
>
<View style={themes[theme] ? themes[theme] : themes.transparent}>
<OriginalComponent
handleCloseModal={this.handleCloseModal}
{...this.props}
/>
</View>
</Modal>
</View>
);
}
};
I have not used getDerivedStateFromProps but, according to the docs, it is called on initial component mount and before each render update.
Thus your code is creating a new interval timer on each update without clearing any of the earlier timers, which could be causing a race condition of some sort.
You may want to consider using the simpler alternatives listed in the docs, or at a minimum, insure that you cancel an interval before creating a new one.

can anyone tell me ,how to use image in a flat-list of react-native?

class App extends Component {
constructor(props) {
super(props)
this.state = {
list: []
};
}
getList = () => {
const li = [
{ key: "image1", imagelink: "" },
{ key: "image2", imgLink: "imagelink" },
{ key: "image3", imgLink: "imagelink" },
{ key: "image3", imgLink: "imagelink" },
]
this.setState({
list: li
})
}
componentWillMount() {
this.getList()
}
render() {
return (
export default App;
You could just google it, but here is an example:
use FlatList for the list. Pass it the data and a render function.
<FlatList
data={this.data}
renderItem={({ item, index }) => this.renderItem(item, index)}
/>
then create the render function in your component:
renderItem(item, index) {
return (
<Image source={{uri: item.image}}/>
)
}
as an example the data is a component variable:
data = [{image: "link"}, {image: "link"}]

How to make dynamic checkbox in react native

I am making a react native application in which i need to make checkbox during runtime.I means that from server i will get the json object which will have id and label for checkbox.Now i want to know that after fetching data from server how can i make checkbox also how can i handle the checkbox , i mean that how many number of checkbox will be there it will not be static so how can i declare state variables which can handle the checkbox.Also how can i handle the onPress event of checkbox.Please provide me some help of code .Thanks in advance
The concept will be using an array in the state and setting the state array with the data you got from the service response, Checkbox is not available in both platforms so you will have to use react-native-elements. And you can use the map function to render the checkboxes from the array, and have an onPress to change the state accordingly. The code will be as below. You will have to think about maintaining the checked value in the state as well.
import React, { Component } from 'react';
import { View } from 'react-native';
import { CheckBox } from 'react-native-elements';
export default class Sample extends Component {
constructor(props) {
super(props);
this.state = {
data: [
{ id: 1, key: 'test1', checked: false },
{ id: 2, key: 'test1', checked: true }
]
};
}
onCheckChanged(id) {
const data = this.state.data;
const index = data.findIndex(x => x.id === id);
data[index].checked = !data[index].checked;
this.setState(data);
}
render() {
return (<View>
{
this.state.data.map((item,key) => <CheckBox title={item.key} key={key} checked={item.checked} onPress={()=>this.onCheckChanged(item.id)}/>)
}
</View>)
}
}
Here's an example how you can do this. You can play with the code, to understand more how it's working.
export default class App extends React.Component {
state = {
checkboxes: [],
};
async componentDidMount() {
// mocking a datafetch
setTimeout(() => {
// mock data
const data = [{ id: 1, label: 'first' }, { id: 2, label: 'second' }];
this.setState({
checkboxes: data.map(x => {
x['value'] = false;
return x;
}),
});
}, 1000);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
{JSON.stringify(this.state)}
</Text>
{this.state.checkboxes.length > 0 &&
this.state.checkboxes.map(checkbox => (
<View>
<Text>{checkbox.label}</Text>
<CheckBox
onValueChange={value =>
this.setState(state => {
const index = state.checkboxes.findIndex(
x => x.id === checkbox.id
);
return {
checkboxes: [
...state.checkboxes.slice(0, index),
{ id: checkbox.id, label: checkbox.label, value },
...state.checkboxes.slice(index+1),
],
};
})
}
value={checkbox.value}
key={checkbox.id}
/>
</View>
))}
</View>
);
}
}

How to uncheck all other checkbox if data is "No Preference"?

How do I uncheck all checkbox if the data is no preference? I don't know how to manipulate the data.
This is the index.js:
import React, { Component } from "react";
import { Text, View } from 'react-native';
import { CheckBox } from 'react-native-elements';
import { Colors } from '../../../themes/';
import style from "./style";
class CCheckBox extends React.Component {
/////////////////////////////
// constructor()
/////////////////////////////
constructor(props, context) {
super(props, context);
console.log('custom/ccheckbox/index.js constructor()');
this.state = {
checked: false,
};
}
/////////////////////////////
// handleCheck()
/////////////////////////////
handleCheck() {
this.setState({ selectedCheckbox }); // update selected item
}
render() {
return (
<CheckBox
iconType='material'
checkedIcon='check'
uncheckedIcon='check-box-outline-blank'
checkedColor={Colors.ORANGE}
checked={this.state.checked}
containerStyle={style.content}
onPress={() => this.handleCheck()}
/>
);
}
}
export default CCheckBox;
And this is my profalcoholpref.js:
import React, { Component } from "react";
import { ScrollView, View } from 'react-native';
import { Content } from 'native-base';
import CButton from '../cbutton/index';
import PopSelectList from './popselectlist';
import styleC from "../../common/style";
import style from "./style";
class PopAlcoholPref extends React.Component {
///////////////////////////////
// constructor()
///////////////////////////////
constructor(props, context) {
super(props, context);
console.log('custom/cfield/popalcoholpref.js constructor()');
this.state = {
selectedCheckbox: {},
visible: this.props.visible,
data: [
{
id : 1,
code : 'DON',
description : 'Do not drink',
},
{
id : 2,
code : 'INF',
description : 'Infrequently',
},
{
id : 3,
code : 'SOC',
description : 'Socially',
},
{
id : 4,
code : 'MOD',
description : 'Moderately',
},
{
id : 5,
code : 'ASN',
description : 'As Needed',
},
{
id : 5,
code : 'NOP',
description : 'No Preference',
},
]
};
}
///////////////////////////////
// componentWillReceiveProps()
///////////////////////////////
componentWillReceiveProps(nextProps) {
console.log('componentWillReceiveProps()');
this.setState({
visible: nextProps.visible
});
}
///////////////////////////////
// handleSave()
///////////////////////////////
handleSave() {
console.log('handleSave()');
this.setState({
visible: false
});
}
///////////////////////////////
// render()
///////////////////////////////
render() {
return (
<View>
<PopSelectList title='Alcohol Preference' data={this.state.data} visible={this.state.visible} handleSave={() => this.handleSave()} />
</View>
);
}
}
export default PopAlcoholPref;
How do I uncheck all other checkbox if no preference is checked? Is there any way I can manipulate the data? Index.js is the frontend and I manipulated the checkbox there and in the prefalcohol is where the data is being stored.
You will need a bit of a refactoring here I beleive.
You should move the state handling logic to the list. In the list you can manipulate all the checkboxes at the same time.
class List extends Component {
constructor(props) {
super(props);
this.state = {
checkBoxesList: [{
id: 1,
checked: false,
}, {
id: 2,
checked: false,
}]
}
}
unCheckAll() {
this.setState({ checkBoxesList: this.state.checkBoxesList.map(({ id }) => ({
id: id,
checked: false,
})) })
}
checkBoxSelected(id) {
const index = this.state.checkBoxesList.findIndex((value) => value.id === id);
this.setState({ checkBoxesList[index]: {
...this.state.checkBoxesList[index],
checked: !this.state.checkBoxesList[index].checked
})
}
renderCheckBoxes() {
return this.state.checkBoxesList.map(({id, checked}) => (
<CheckBox id={id} checked={checked} onPress={this.checkBoxSelected} />
))
}
render() {
return (
<View>
{this.renderCheckBoxes()}
</View>
)
}
}
So this Component handles the states for the checkboxes. You need to make sure that you also implement the callback inside the CheckBox component for the OnPress method. Now calling the UncheckAll method will uncheck all the checkboxes.
But also you have to put in some extra check before setting the checkBoxesList if the index does exist.