Torben
Torben

Reputation: 5494

React Native - Passing data from a component to another

I took over a React Native project from somebody else, this project is quite old (2 years) and I came across the following:

Home.js Component: (I simplified it)

export let customersData = null;

export default class Home extends Component {  

    render() {
        return (
            <JumboButton
                onPress={() => {
                  this.props.navigator.push({
                    component: CustomerSearch
                  });
                }}
              >
        );
    }

    _getAllCustomers(limit, sortAttr, order) {
        apiCall.(apiUrl, {
        ...
        }).then((responseData) => {
            const customersDataAll = responseData.data;
            customersData = customersDataAll.filter((f) => {
                return f.lastname !== ''
            });
        });
    }
}

So within the Home-Component, customersData is filled with data. Also the component CustomerSearch is called and within CustomerSearch I found this:

CustomerSearch.js:

import {customersData} from './Home';

export default class CustomerSearch extends Component {
    constructor(props) {
        super(props);
        this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.state = {
            dataSource: this.ds.cloneWithRows(customersData),
        };
    }
}

Two things are a bit weird for me:

  1. Is it correct to set customersData and not this.customersData inside the callback of the api call?

  2. Currently I get this error https://d.pr/i/IUzxdf "Cannot convert undefined or null to object" and I assume that this is because of the data import of customersData in CustomerSearch.js. Is the place where I need to look? Btw is there any chance that react tells me the exact line and file where this error occurs?

Thanks for your help!

Upvotes: 0

Views: 66

Answers (1)

fredmoon
fredmoon

Reputation: 94

  1. Short answer is that it is definitely an unusual React pattern, and not one that many people would recommend. Importing a let variable into another file is not a reliable way to share information between components.

It would be far more sensible to attach customersData to your parent component's state and pass it to CustomersSearch through a prop - i.e.

export default class Home extends Component {
  constructor (props) {
     super(props);
     this.state = { customersData: null };
     this._getAllCustomers = this._getAllCustomers.bind(this)
  }

  render() {
    return (
        <JumboButton
          onPress={() => {
            this.props.navigator.push({
              component: props =>
                <CustomerSearch customersData={this.state.customersData} {...props} />
            });
          }}
        >
    );
  }

  _getAllCustomers(limit, sortAttr, order) {
    apiCall.(apiUrl, {
    ...
    }).then((responseData) => {
        const customersDataAll = responseData.data;
        const customersData = customersDataAll.filter((f) => {
            return f.lastname !== ''
        });
        this.setState({ customersData });
    });
  }
}

Not sure how your JumboButton's onPress prop works exactly, but you should get the idea?

And in answer to 2. - Yes I would imagine this is the problem!

Upvotes: 1

Related Questions