myTest532 myTest532
myTest532 myTest532

Reputation: 2381

React Native reusable edit component

I'm trying to create a reusable component in react native. The idea is to have only one component responsible to edit all the fields that I have.

Main Component

...
constructor(props) {
    super(props);
    this.state.FirstName = 'Joe'
  }
...
const { FirstName } = this.state.FirstName;
<TouchableOpacity
    onPress={() =>
       NavigationService.navigate('EditData', {
           label: 'First Name',
           initialValue: FirstName,
           onSubmit: (FirstName) => this.setState({ FirstName })
       })
    }
>
    <CardItem>
        <Left>
            <FontAwesome5 name="user-edit" />
            <Text>First Name</Text>
        </Left>
        <Right>
            <Row>
                <Text style={styles.valueText}>{FirstName}   </Text>
                <Icon name="arrow-forward" />
            </Row>
        </Right>
    </CardItem>
</TouchableOpacity>
// Keep doing the same for other fields

Then, the edit component should be reusable.

constructor(props) {
    super(props);

    // callback function
    this.onSubmit = props.navigation.getParam('onSubmit');
    // label/value
    this.state = {
      label: props.navigation.getParam('label'),
      value: props.navigation.getParam('initialValue')
    };
  }

  render() {
    const { onSubmit } = this;
    const { label, value } = this.state;

    return (
      <Container>
        <Header />
        <Content>
          <Item floatingLabel style={{ marginTop: 10 }}>
            <Label>{label}</Label>
            <Input
              value={value}
              onChangeText={val => this.setState({ value: val })}
            />
          </Item>
          <Button
            onPress={() => {
              onSubmit(value);
              NavigationService.navigate('TenantDetails');
              }
            }
          >
            <Text>OK</Text>
          </Button>
        </Content>
      </Container>
    );
  }

When back to the main component, the first name value was not changed.

My NavigationService in case it might be the problem:

import { NavigationActions } from 'react-navigation';

let _navigator;

function setTopLevelNavigator(navigatorRef) {
  _navigator = navigatorRef;
}

function navigate(routeName, params) {
  _navigator.dispatch(
    NavigationActions.navigate({
      routeName,
      params,
    })
  );
}

// add other navigation functions that you need and export them

export default {
  navigate,
  setTopLevelNavigator,
};

Thanks

Upvotes: 1

Views: 148

Answers (1)

Mateusz Siniarski
Mateusz Siniarski

Reputation: 1015

You could pass a callback to your new component which handles this. The new component would start with a state with the initialValue set. It looks like you might be using react-navigation so I would recommend that if you want this component on its own screen you could do

this.navigation.navigate('SetValueScreen', {
  initialValue: this.state.email,
  onSubmit: (email) => this.setState({ email })
})

and on the SetValueScreen get the initialValue in the constructor and in the render use the callback

class SetValueScreen extends React.PureComponent{
  constructor(props){
    super(props)

    this.onSubmit = props.navigation.getParam('onSubmit');

    this.state = {
      value: props.navigation.getParam('initialValue')
    }
  }

  render(){
    const { onSubmit } = this
    const { value } = this.state

    return (
      ...    
      <Right>
        <TextInput value={value} onChangeText={(value) => setState({ value })} />
      </Right>
      <Button onPress={() => {
        onSubmit(value)
        navigation.goBack()
      }} >
        OK
      </Button>
      ...
    )
  }
}

I hope this helps.

Upvotes: 1

Related Questions