简体   繁体   中英

How to implement a callback in React/Redux

I have a function that I would like to put in a separate file. The problem is that the function makes a request that takes some amount of time. I want to have that function in another file and be able to call it and only when I get the correct data back proceed.

I will post the function only, but if you need more information I will post the rest of the file, but it is large and has a lot of clutter so it may be hard to read with all the code.

I want to be able to have something like this while being able to do all the things I can do now with the function on the same page.

submitRadius(items, userRadius, (err, response) => {
    if(err){console.log(err)}
    console.log(response)

});

Function:

submitRadius(userRadius) {
    const { items } = this.props;
    const markers = [];
    items.map((item, i) => {
      const newGeoArr = item.geolocation.split(',');
      if (
        newGeoArr.length > 1 &&
        newGeoArr !== '' &&
        newGeoArr[0] !== undefined &&
        newGeoArr[0] !== null
      ) {
        item.position = { lat: Number(newGeoArr[0]), lng: Number(newGeoArr[1]) };
        item.distance = { latitude: Number(newGeoArr[0]), longitude: Number(newGeoArr[1]) };
        geolocation.getCurrentPosition((position) => {
          const currentLocation = {
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
          };
          const distanceArr = geolib.orderByDistance(currentLocation, [item.distance]);
          const miles = (distanceArr[0].distance / 1609.34).toFixed(2);
          if (miles <= userRadius) {
            markers.push({
              position: item.position,
              number: i,
              content: item.description,
              showInfo: false,
            });
            this.setState({
              markers,
            });
          }
        });
      }
    });
    this.setState({
      markers,
    });
  }

You simply define your function such that it takes the callback function as an argument; for instance:

submitRadius(radius, callback) {
    ... do stuff such that err and response will be produced ....
    callback(err, response);
}

Then call your function thus:

... do stuff
submitRadius(radius, (err, response) => { ... })

I do strongly suggest you look into promises though, as supplying callbacks is only easily readable in simple scenarios; when things get more complex, promises (or async/await) are simpler to manage.

You can simply write the same function in a separate submitRadius.js file and replace setState with a callback function as follows.

function submitRadius(items, userRadius, callback) {
  const markers = [];
  items.map((item, i) => {
    const newGeoArr = item.geolocation.split(",");
    if (
      newGeoArr.length > 1 &&
      newGeoArr !== "" &&
      newGeoArr[0] !== undefined &&
      newGeoArr[0] !== null
    ) {
      item.position = { lat: Number(newGeoArr[0]), lng: Number(newGeoArr[1]) };
      item.distance = {
        latitude: Number(newGeoArr[0]),
        longitude: Number(newGeoArr[1])
      };
      geolocation.getCurrentPosition(position => {
        const currentLocation = {
          latitude: position.coords.latitude,
          longitude: position.coords.longitude
        };
        const distanceArr = geolib.orderByDistance(currentLocation, [
          item.distance
        ]);
        const miles = (distanceArr[0].distance / 1609.34).toFixed(2);
        if (miles <= userRadius) {
          markers.push({
            position: item.position,
            number: i,
            content: item.description,
            showInfo: false
          });
          callback(markers);
        }
      });
    }
  });
  callback(markers);
}

Now after calling the function, inside the callback, you can use setState with the response.

submitRadius(items, userRadius, (err, response) => {
  if(err){
    console.log(err)
  } else {
    this.setState({ markers : response})
    console.log(response)
  }
});

I'm not sure what's geolocation in your function. You may have to import it inside submitRadius.js file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM