React Native – Do 3 steps in one onPress: (1) send POST req, (2) receive POST res (including ID created by post), (3) navigate with ID as param

  Kiến thức lập trình

I am working on a project in React Native where the user navigates from a “Create Artist” screen to the “Artist Page” by clicking a button. When the user clicks this button, I want three things to happen:

  1. send a POST request to create the new Artist (via an API call from my reducer to the backend
  2. receive the POST response which includes info about the new artist, including the artist_id which was created automatically by the database (the info sent as the body of the POST request comes from what the user filled in on the “Create Artist” screen prior to clicking the button), and
  3. navigate to the Artist Page, including the newly created artist_id in the params.

The Artist Page will then use this artist_id to search through all artists to find the newly created one and populate the Artist Page with that info. I want to use the artist ID in the params instead of passing the state because the user can navigate to the Artist Page from several other screens, and it’s easier to use the id from the params in all cases to find the relevant artist. FYI I’m not using redux – I built my own reducer.

**Create Artist Screen:**
```const CreateArtist = ({ navigation }) => {
const { state: artist, addArtist } = useContext(ArtistContext);
const { state: user, getUser } = useContext(AuthContext);

const [artist_name, setartist_name] = useState("");
const [artist_genre, setartist_genre] = useState("");
const [newArtistState, setNewArtistState] = useState("");

const newArtist = artist[0];
const { artist_id } = newArtist;
**console.log(artist_id)**

 const user_id = user.user_id;
 const popAction = StackActions.pop(1);

 return (
<View>
  <TouchableOpacity
    onPress={() => navigation.dispatch(popAction)}
    style={styles.backIcon}
  >
    <AntDesign name="back" size={24} color="black" />
    <Text>Back</Text>
  </TouchableOpacity>
  <Text style={styles.headerTitle}>MY ARTISTS</Text>
  <Text style={styles.label}>Artist Name:</Text>
  <TextInput
    style={styles.input}
    value={artist_name}
    onChangeText={setartist_name}
  />

  <Text style={styles.label}>Genre:</Text>
  <TextInput
    style={styles.input}
    value={artist_genre}
    onChangeText={setartist_genre}
  />
  <Spacer>
    <Button
      title="Create Artist"
      onPress={
        {async () =>
        await addArtist({
          user_id,
          artist_name,
          artist_genre,
        })
      }
        navigation.navigate('Artist Page', {artist_id}
    />
  </Spacer>
  </View>
  );
  };```

Reducer with “Add Artist” post request:
“`const artistReducer = (state, action) => {
switch (action.type) {
case “add_artist”:
return action.payload;
default:
return state;
}
};

const addArtist =
(dispatch) =>
  async ({
    user_id,
    artist_name,
    artist_genre,
    artist_email,
    artist_location,
    artist_description,
    artist_instagram,
    artist_spotify,
    artist_youtube,
    artist_website,
   }) => {
   const response = await ensemblersApi.post("/artists", {
    user_id,
    artist_name,
    artist_genre,
    artist_email,
    artist_location,
    artist_description,
    artist_instagram,
    artist_spotify,
    artist_youtube,
    artist_website,
   });

   dispatch({ type: "add_artist", payload: response.data });
   };```

** Artist Page:**

const { state: user, getUser } = useContext(AuthContext);
const { state: artistState, getArtist } = useContext(ArtistContext);
const [artist, setArtist] = useState([]);

const { artist_id } = route.params;

 useEffect(() => {
 const fetchdata = navigation.addListener("focus", async () => {
   const artistInfo = await getArtist(artist_id);
   setArtist(artistInfo);
 });
 return fetchdata;
 }, [navigation]);

const { user_id } = user;
const artistUser = artistState[0];

 const artist_user_id = artistUser.user_id;

 const {
 artist_name,
 artist_genre,
 artist_email,
 artist_location,
 artist_description,
 artist_instagram,
 artist_spotify,
 artist_youtube,
 artist_website,
 } = artistState[0];

 console.log(artist);

 const popAction = StackActions.pop(1);

 return (
 <View>
   <TouchableOpacity
     onPress={() => navigation.navigate("My Stuff")}
     style={styles.backIcon}
   >
     <AntDesign name="back" size={24} color="black" />
     <Text>Back</Text>
   </TouchableOpacity>
   <View style={styles.container}>
     {artist_user_id === user_id ? (
       <TouchableOpacity
         onPress={() =>
           navigation.navigate("Edit Artist Page", { artist_id })
         }
         style={styles.editIcon}
       >
         <AntDesign name="edit" size={24} color="grey" />
       </TouchableOpacity>
     ) : null}
     <Text style={{ marginVertical: 20, fontSize: 30 }}>{artist_name}</Text>
     <Text style={{ fontSize: 20 }}>{artist_genre}</Text>
     <Text style={{ fontSize: 20 }}>{artist_email}</Text>
     <Text style={{ fontSize: 20 }}>{artist_location}</Text>
     <Text style={{ fontSize: 20 }}>{artist_description}</Text>
     <Text style={{ fontSize: 20 }}>{artist_instagram}</Text>
     <Text style={{ fontSize: 20 }}>{artist_spotify}</Text>
     <Text style={{ fontSize: 20 }}>{artist_youtube}</Text>
     <Text style={{ fontSize: 20 }}>{artist_website}</Text>
     {artist_user_id === user_id ? (
       <Button
         title="Manage Gigs"
         buttonStyle={{
           backgroundColor: "rgba(78, 116, 289, 1)",
           borderRadius: 3,
         }}
         containerStyle={{
           width: 200,
           marginHorizontal: 50,
           marginVertical: 10,
           borderRadius: 30,
         }}
         onPress={() => {
           navigation.navigate("Artist Gig Manager");
         }}
       />
     ) : null}
   </View>
 </View>
 );
 };````



So far, I can send the POST request and get the artist_id to show up in the console log (see bold line in the Artist Screen code below). But when I add the navigation function to the OnPress function, it crashes. rough all artists to find the newly created one and populate the Artist Page with that info. I want to use the artist ID in the params instead of passing the state because the user can navigate to the Artist Page from several other screens, and it's easier to use the id from the params in all cases to find the relevant artist. Could someone please help?

New contributor

Jeff Hoffmann is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

LEAVE A COMMENT