how bind correctly in react-native? - javascript

I'm try to update the state from a function, but I don't find the correct form to bind the scope. My code (I am working with native-base components):
export default class MenuScreen extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
_renderRow() {
return (
<ListItem avatar onPress={() =>
ActionSheet.show(
{options: BUTTONS
}, buttonIndex => { setState({ clicked: BUTTONS[buttonIndex]})}
)}
>
</ListItem>
);
}
render() {
return (
<SectionList
sections={[...]}
renderItem={this._renderRow}
/>
);
}

First option, bind it in constructor
Example
constructor(props) {
super(props);
this.state = {};
this._renderRow = this._renderRow.bind(this);
}
Second option, bind it inline
Example
<SectionList
sections={[...]}
renderItem={this._renderRow.bind(this)}
/>
Third option, use arrow functions
Example
renderRow = () => {
return (
<ListItem avatar onPress={() =>
ActionSheet.show(
{options: BUTTONS
}, buttonIndex => { this.setState({ clicked: BUTTONS[buttonIndex]})}
)}
>
</ListItem>
);
}

My recommendation would be to read this:
https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56
Helps a lot with understanding binding options you have and why one or other might be better in your case.
I suggest to go with binding in constructor:
export default class MenuScreen extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.handleChange = this.handlePress.bind(this);
}
...

self mental note, "Bind is dummy if I not use the context of the function"
export default class MenuScreen extends React.Component {
constructor(props) {
super(props);
this.state = {};
**this._renderRow = this._renderRow.bind(this);**
}
_renderRow() {
return (
<ListItem avatar onPress={() =>
ActionSheet.show(
{options: BUTTONS
}, buttonIndex => { **this.**setState({ clicked: BUTTONS[buttonIndex]})}
)}
>
</ListItem>
);
}
render() {
return (
<SectionList
sections={[...]}
renderItem={this._renderRow}
/>
);
}

Related

I can't update state in child component

i wanna change state value in child component but i getting always 'this.setState is not a function ' error
Parent Component
`
export default class Todo extends Component {
constructor(props){
super(props)
this.state = {
propBottomMenu : false
}
this.bottomRef = React.createRef()
};
checkClose(){
this.setState({propBottomMenu : false})
}
render() {
return (
<>
// other codes
<TouchableOpacity
onPress={() => this.setState({propBottomMenu : false})}
style={styles.addTask}
>
<FontAwesomeIcon icon={ faPlus } size={25} color={'#fff'} />
</TouchableOpacity>
{this.state.propBottomMenu ?
<BottomMenu bSheetRef={this.bottomRef} checkClose={this.checkClose} style= {styles.bottomMenu} />
: null}
</>
)
}
}
`
Child Component :
`
export default class BottomMenu extends Component {
constructor(props){
super(props)
this.bottomRef = this.props.bSheetRef
}
render() {
return (
<>
<BottomSheet
ref={this.bottomRef}
snapPoints={[ '40%', '60%', '90%']}
index={1}
enablePanDownToClose={true}
onChange={(index)=>{ index < 0 && this.props.checkClose() }}
>
// other codes
</BottomSheet>
</>
)
}
}
})
`
checkClose() function working but i can't update state
Error : this.setState is not a function
Solution :
For the function to work we must use bind or call it as arrow function
constructor(props){
super(props)
this.checkClose = this.checkClose.bind(this); // this line
this.state = {
propBottomMenu : false
}
this.bottomRef = React.createRef()
};
Jsx:
<BottomMenu bSheetRef={this.bottomRef} checkClose={this.checkClose} style={styles.bottomMenu} />

this2.props.addToList is undefined, List creation error

Diet.js
export class Diet extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
};
this.addToList = this.addToList.bind(this);
}
addToList(item) {
const list = [...this.state.list, item];
this.setState({ list });
}
render() {
<FoodCreate addToList={this.addToList} />
return (
<FoodList items={this.state.list} />
)}
FoodCreate
export class FoodCreate extends Component {
constructor(props) {
super(props);
this.state = {
FoodName: "",
calories: 0,
};
}
render() {
return (
<Button transparent>
<Icon
name="checkmark"
style={{ fontSize: 25, color: "red" }}
onPress={() => this.props.addToList(FoodName, calories)}
/>
</Button>
<TextInput
placeholder="Food Name"
placeholderTextColor="white"
style={styles.inptFood}
value={FoodName}
onChangeText={(FoodName) => this.setState({ FoodName: FoodName })}
/>
<TextInput
placeholder="Calories"
placeholderTextColor="white"
style={styles.inptMacros}
keyboardType="numeric"
value={calories}
maxLength={5}
onChangeText={(calories) => this.setState({ calories: calories })}
/>
FoodList
export class FoodList extends Component {
render() {
return (
<Content>
<List>
<ListItem itemDivider>
<Text>Food</Text>
{this.props.items.map((item, index) => {
return (
<ListItem key={index}>
<Text>{item.FoodName}</Text>
<Text>{item.calories}</Text>
</ListItem>
);
})}
</ListItem>
</List>
</Content>
);
}
}
export default FoodList;
Hi, I'm new to programming and React Native, so I'm trying to create a Grocery List by letting the user type FoodName and Calories and pressing the Icon: Check in FoodCreate page, and List it in the FoodList page, at the moment when I run the code gives me back an error: _this2.props.addToList is not a function, I've tried many solutions but I'm not sure where the error is.
class FoodCreate extends Component {
render() {
return (
<Button title="aaa" onPress={() => this.props.addToList('name')}></Button>
);
}
}
export default class Diet extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
};
this.addToList = this.addToList.bind(this);
}
addToList(item) {
const list = [...this.state.list, item];
this.setState({list});
}
render() {
return <FoodCreate addToList={this.addToList} />;
}
}
I use the above code and didn't get the error
But I think you can have a better code
Don't use this.addToList = this.addToList.bind(this);, you can convert addToList to arrow function and remove this line
addToList = item => {
const list = [...this.state.list, item];
this.setState({list});
};

How can I do a field in react-admin taking as input a icon from IconPicker?

I want to do a field input where it takes a icon from IconPicker. How can I do ?
I've tried to do something like that:
in hardware.js
export const HardwareCreate = (props) => (
<Create title={<AppTitle />} {...props}>
<SimpleForm>
...other normal fields...
<TextField label="Ícone"/>
<IconPicker source="icon"/>
</SimpleForm>
</Create>
);
And in iconpicker.js
class IconPicker extends Component {
constructor(props) {
super(props);
this.state = {
value: 'fipicon-angle-left',
};
}
handleChange = (value) => {
this.setState({ value });
console.log(this);
}
render() {
const props = {
icons: ['fipicon-angle-left', 'fipicon-angle-right', 'fipicon-angle-up', 'fipicon-angle-down'],
theme: 'bluegrey',
renderUsing: 'class',
value: this.state.value,
onChange: this.handleChange,
isMulti: false,
};
return (
<FontIconPicker {...props}/>
);
}
export default IconPicker;

React Native - Execute child function from Parent Button onPress

Disclaimer : I'm new to RN. I have already tested multiple solutions from other similar questions without success so far.
I have a Parent that render two Childrens like this
export default class ParentComponent extends Component {
constructor(props) {
super(props)
}
render() {
return (
<View>
<Foo name="a" ref={foo => {this.foo = foo}} {...this.props} />
<Text>-----------</Text>
<Foo name="b" />
<Text>-----------</Text>
<Button
onPress={this.foo.myFunction()}
title="Start"
color="#841584"
/>
</View>
)
}
}
My class Foo has a function inside it that start some process :
class Foo extends Component {
myFunction(){
// Some stuff here
}
}
How can I call this myFunction for my Child when I press on the Button ? Optionally, is it possible with only one onPress, to call the function for both Child and avoid creating two Button for each Child ?
You can use refs
https://reactjs.org/docs/refs-and-the-dom.html
Example:
class Parent extends Component {
render() {
return (
<View>
<Child ref={instance => { this.child = instance; }} />
<TouchableOpacity onPress={() => { this.child.clicked(); }}>
<Text>Click</Text>
</TouchableOpacity>
</View>
);
}
}
class Child extends Component {
clicked() {
alert('clicked');
}
render() {
return (
<Text>Hello</Text>
);
}
}
Hope it helps
Basically what I did is to call a local function when onPress and change the state of the Parent. I pass this state to the Child during its creation. And since the Child are updated (if needed) when the Parent's state change this do the trick.
export default class ParentComponent extends Component {
constructor(props) {
super(props)
this.state = {
activity: false
}
}
onButtonPress = () => {
this.setState({
activity: !this.state.activity
});
}
render() {
return (
<View>
<Foo name="a" activity={this.state.activity} />
<Text>-----------</Text>
<Foo name="b" activity={this.state.activity} />
<Text>-----------</Text>
<Button
onPress={this.onButtonPress}
title="Start"
color="#841584"
/>
</View>
)
}
}
class Foo extends Component {
myFunction(){
// Some stuff here
}
componentWillReceiveProps(newProps) {
if (newProps.activity === true) {
this.myFunction();
}
}
}
It's better to do myFunction logic inside ParentComponent and setState the data which can be passed into child ie:Foo.
constructor(props) {
super(props);
this.state = {
fooData: initialValue,
}
}
myFunction = () => {
// Some stuff here
this.setState({ fooData: someValue })
}
render() {
return (
<View>
<Foo name="a" data={this.state.fooData} {...this.props} />
<Text>-----------</Text>
<Foo name="b" data={this.state.fooData}/>
<Text>-----------</Text>
<Button
onPress={this.myFunction}
title="Start"
color="#841584"
/>
</View>
)
}
and you can make the changes inside Foo accordingly
class Foo extends Component {
render() {
const { data } = this.props;
return(
//Use data here to make change
)
}
}

React-native passing component to another

I would like to pass one React component to my CustomTab component.
So i have something like this :
const FirstRoute = () => <View style={[ styles.container, { backgroundColor: '#ff4081' } ]} />;
const SecondRoute = () => <View style={[ styles.container, { backgroundColor: '#673ab7' } ]} />;
export default class Profile extends Component {
_renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
render() {
return (
<CustomTab scenes={this._renderScene}/>
);
}
In my CustomTab i have :
export default class CustomTab extends React.Component {
_renderScene = this.props.scenes;
render() {
return (
<TabViewAnimated
style={styles.container}
navigationState={this.state}
renderScene={this._renderScene}
but this is not working, looks like passed parameter is wrong .It is possible to achieve that ?
Thx for any help.
You should set _renderScene property in constructor or other react component life cycle methods like.
constructor(props) {
super(props);
this._renderScene = this.props.scenes;
}
Your syntax is wrong, you need to assign _renderScene variable in render or constructor however there is not need for you to assign this.props.scenes to another class variable you could just directly use it
export default class CustomTab extends React.Component {
render() {
return (
<TabViewAnimated
style={styles.container}
navigationState={this.state}
renderScene={this.props. scenes}

Categories

Resources