How to call function inside another function>
For example
I have 2 cascade dropdown which value from second dropdown depends on from first dropdown. inside the first dropdown there is a method like this
`onValueChange = {(value)=>{this.props.getSecondValue(value.id)}}.`
My question is why every time I change the value from first dropdown it causes infinite loop in this.props.getSecondValue() function?
How to solve that problem.
Many thanks !
update
here my snippet code
import React, {Component} from 'react';
import {StyleSheet, Text, View, TouchableOpacity, KeyboardAvoidingView, SafeAreaView, ScrollView} from 'react-native';
import {bindActionCreators} from "redux";
import {RootActions} from "../../shared/root-actions";
import connect from "react-redux/es/connect/connect";
import Config from 'react-native-config';
import _ from 'lodash';
import {Dropdown} from 'react-native-material-dropdown';
type Props = {};
const styles = StyleSheet.create({
container: {
flex: 1
}
});
class Index extends Component<Props> {
constructor(props) {
super(props);
this.state = {
point_type_id: '',
point_category_id: '',
}
this._getPointTypes = this._getPointTypes.bind(this);
this._getPointCategories = this._getPointCategories.bind(this);
}
componentDidMount() {
this._getPointTypes();
}
_getPointTypes(){
this.props.getPointTypes();
}
_getPointCategories(point_type_id){
this.props.getPointCategories(point_type_id);
}
render() {
let {
point_type_id,
point_category_id,
} = this.state;
let {
} = this.locationDetailStates;
return (
<View style={styles.container}>
....
<Dropdown
label='Point types'
data={point_types}
labelExtractor = {(value)=>{this._getPointCategories(value.id)}}
/>
<Dropdown
label='Point categories'
data={point_categories}
/>
</View>
);
}
}
function mapStateToProps(state) {
return {
outdoorStates: state.outdoorStates,
locationDetailStates:state.locationDetailStates
}
}
function mapDispatchToProp(dispatch) {
return bindActionCreators(RootActions, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProp)(Index);
Try to refactor like this:
function mapDispatchToProps(dispatch) {
return {
getSecondValue: (id)=>{
//Your code here
}
}
}
class MyClass extends React.Component {
handleChange = (e)=>{
//assign your id from event values
this.props.getSecondValue(id);
}
...
render(){
return (
//inside a tag
onChange = {this.handleChange}
)
}
}
Related
I have the following parent React component. I would like to either pass the meeting.settings.ae (array of object) to the child useState Component. Don't know how I can fix it.
import React, {Component} from 'react';
import AEModal from "./AEModal";
export default class MAT extends Component {
constructor(props) {
super(props);
this.state = {
ae: !!meeting.settings.ae ? meeting.settings.ae : ""
};
}
getMeetingAEArray = () => {
let setting = this.state.settings();
return !!setting && !!setting.ae ? setting.ae : null;
}
getMeetingAE = () => {
return <AEModal
meeting={() => {
return this.state.meeting;
}}
AEArray={() => {
return getMeetingAEArray();
}}
/>
}
}
The child class
import React, { useState } from "react";
import i18n from 'Components/translations/i18n';
import {
Icon,
} from '#components';
function AEModal(props) {
const [form, setForm] = useState([]);
let meeting = props.meeting();
let ae = meeting.settings.ae; //ae is undefined
let aeArray = props.getAEArray();
}
To pass props coming from parent, you can do it as follows.
Following is an example. Please modify it for your implementation.
import React, { Component } from "react";
import AEModal from "./AEModal";
export default class MAT extends Component {
render() {
return (
<AEModal
meeting={this.props.meeting}
/>
);
};
}
Child component
import React, { useState } from "react";
function AEModal(props) {
console.log("meeting: ", props.meeting);
return <div>{props.meeting}</div>;
}
I'm really regarding props in React/React-Native. I have a parent view. In this view I'm getting the user data from a LocalStorage.['
import React, { Component } from 'react';
import { Container, Content, View } from 'native-base';
import NutrionalToolbar from '../../components/NutrionalToolbar';
import { AsyncStorage } from 'react-native';
export default class LogsScreen extends Component {
state = {
user: '',
}
componentWillMount() {
this._bootstrapAsync();
}
_bootstrapAsync = async () => {
const user = await AsyncStorage.getItem('user');
this.setState({ user: JSON.parse(user) })
};
render() {
return (
<Container>
<NutrionalToolbar user={this.state.user} />
</Container>
);
}
}
Now inside the NutrionalToolbar component I have this.
import React, { Component } from 'react';
import { View } from 'native-base';
class NutrionalToolbar extends Component {
constructor(props) {
super(props)
console.log(this.props) // This renders an empty user object
}
render() {
console.log(this.props) // This renders the user object with values
return (
<View>
</View>
);
}
}
export default NutrionalToolbar;
How can I get this.props values inside the constructor. I'm getting the values inside render method. Why isn't working inside the constructor?
I would recommend looking into the componentDidUpdate lifecycle hook because, even if you could access the initial user prop in the constructor, you wouldn't be able to access updates to that prop in the constructor.
import React, { Component } from 'react';
import { View } from 'native-base';
class NutrionalToolbar extends Component {
componentDidUpdate() {
console.log(this.props) // This will always log the current props
}
render() {
return (<View></View>);
}
}
export default NutrionalToolbar;
I'm trying to render a flatlist by connecting to a internal JSON file. The flatlist seems to be rendering but not showing any text. The cardlist in the code is being rendered 9 times, there are 9 objects in the JSON file. But no text is showing.
// libraryList.js
import React, { Component } from 'react';
import { FlatList } from 'react-native';
import { connect } from 'react-redux';
import ListItem from './ListItem';
class LibraryList extends Component {
renderItem(library) {
return <ListItem library={library} />;
}
render() {
// console.log(this.props);
// return;
return (
<FlatList
data={this.props.libraries}
renderItem={this.renderItem}
keyExtractor={library => library.id}
/>
);
}
}
const mapStateToProps = state => {
return { libraries: state.libraries };
};
export default connect(mapStateToProps)(LibraryList);
// ListItem.js
import React, { Component } from 'react';
import { Text } from 'react-native';
import { CardSection } from './common';
class ListItem extends Component {
render() {
return (
<CardSection>
<Text>{this.props.library.title}</Text>
</CardSection>
);
}
}
export default ListItem;
import React, { Component } from 'react';
import { Text } from 'react-native';
import { CardSection } from './common';
class ListItem extends Component {
render() {
return (
<CardSection>
<Text>{this.props.library.title}</Text>
</CardSection>
);
}
}
export default ListItem;
Just want to list the title at this stage.
You need to modify renderItem because FlatList passes an object into the renderItem callback function.
Instead, use the below
renderItem = ({ item }) => <ListItem library={item} />
Thanks Dan you put me onto the right lines. I used
renderItem={({ item }) => this.renderItem(item)}
I am trying to update state in react native component.
But its getting errors, Could someone help me.
I'm using react-native-cli verions: 2.0.1
react-native verions: 0.55.4
Here is my code:
import React, { Component } from 'react'
import {
Button,
Text,
View,
} from 'react-native';
export class ToggleButton extends Component {
state = {
isDone: false
};
onAction() {
const value = !this.state.isDone;
this.setState({ isDone: value });
const newValue = this.state.isDone;
console.log(newValue);
}
render() {
return (
<View>
<Button
title="Action"
onPress={this.onAction}
/>
</View>
)
}
}
export default ToggleButton;
You have three different solutions.
Bind your function in the constructor.
Use the experimental public class fields syntax.
Pass a lambda to executing your function.
The problem is that you're loosing the reference to this, because the function is not executed in the original context, so this.setState is not a function, but a undefined.
In this page there are examples for all of the approaches: https://reactjs.org/docs/handling-events.html
Change
onPress={this.onAction}
to
onPress={this.onAction.bind(this)}
Check: this
Below is the solution
import React, { Component } from 'react'
import {
Button,
Text,
View,
} from 'react-native';
export class ToggleButton extends Component {
// Add state in constructor like this
constructor(props){
super(props);
this.state = {
isDone: false
};
}
onAction() {
const value = !this.state.isDone;
this.setState({ isDone: value });
const newValue = this.state.isDone;
console.log(newValue);
}
render() {
return (
<View>
<Button
title="Action"
// Add function with onPress
onPress={() => this.onAction}
/>
</View>
)
}
}
export default ToggleButton;
I have a container which has access to the Redux state and maps a certain pieces of that state to its props, the piece I'm interested in is 'coins' so
this.props.coins
Using console.log() I can see that when rendering the container I have access to that piece of state.
This container houses one component that receives a callback function and this previously mentioned piece of state, coins, via its own props in
onClickHandler() && coinData
The container has a function to handle the callback called
_handleClick()
In this function for some reason this.props doesn't give access to the same coins I was able to access in the render function but has access to the props that I'm passing to the component, props I thought would belong to the component. So from _handleClick() in the container I have access to
this.props.onClickHandler() && this.props.coinData
but not
this.props.coins
which is what I was expecting to have access to from anywhere within my container. I get the error in the title of the post when I try to access this.props.coins in my callback handler _handleClick() but why is that and why do I have access to the props that should belong to the corresponding child component? Is there any way that I can access this.props.coins from the _handleClick() call?
My container:
import React, { Component } from 'react';
import '../App.css';
import { connect } from "react-redux";
import ChartSelectMenu from '../components/ChartSelectMenu';
import { selectCoinForChart } from '../actions/index';
class ChartSelectMenuContainer extends Component {
constructor(props) {
super(props);
}
_handleClick(ticker) {
//event.preventDefault();
console.log("Clicked: ", ticker);
console.log("coin_list: ", this.props);
const coin_list = this.props.coins;
//
for (let i=0; i<coin_list.length; i++) {
if (coin_list[i].ticker === ticker) {
this.props.dispatch(selectCoinForChart(ticker));
}
}
}
render() {
console.log("Container props on render(): ", this.props);
return (
<ChartSelectMenu
onClickHandler={this._handleClick}
coinData={this.props.coins}
/>
);
}
}
function mapStateToProps({ auth, coins, selectedCoin }) {
return { auth, coins, selectedCoin };
}
export default connect(mapStateToProps)(ChartSelectMenuContainer);
It's component:
import React, {Component} from 'react';
import Paper from 'material-ui/Paper';
import Menu from 'material-ui/Menu';
import MenuItem from 'material-ui/MenuItem';
const style = {
display: 'inline-block',
margin: '16px 0px 16px 0px',
};
class ChartSelectMenu extends Component {
constructor(props) {
super(props);
}
_renderMenuItems() {
if (this.props === null) {
return <h3>Loading...</h3>;
} else {
return(this.props.coinData.map((coin) => {
return <MenuItem
key={coin.ticker}
onClick={this.props.onClickHandler.bind(this, coin.ticker)}
primaryText={coin.ticker}
/>
}));
}
}
render() {
//console.log('ChartSelectMenu props: ', this.props);
return (
<div>
<Paper style={style}>
<Menu>
<ul>
{this._renderMenuItems()}
</ul>
</Menu>
</Paper>
</div>
)
}
}
export default ChartSelectMenu;
When #MukulSharma commented 'use var self = this inside your function' I thought to try to bind the _handleClick function in the constructor of the container and it worked.
The solution:
import React, { Component } from 'react';
import '../App.css';
import { connect } from "react-redux";
import ChartSelectMenu from '../components/ChartSelectMenu';
import { selectCoinForChart } from '../actions/index';
class ChartSelectMenuContainer extends Component {
constructor(props) {
super(props);
this._handleClick = this._handleClick.bind(this);
}
_handleClick(ticker) {
//event.preventDefault();
console.log("Clicked: ", ticker);
console.log("coin_list: ", this.props);
const coin_list = this.props.coins;
//
for (let i=0; i<coin_list.length; i++) {
if (coin_list[i].ticker === ticker) {
this.props.dispatch(selectCoinForChart(ticker));
}
}
}
render() { ...