J'essaie de passer le dernier message des utilisateurs dans l'accessoire de sous-titres ListItem mais je n'arrive pas à trouver un moyen de renvoyer la valeur de la promesse / puis d'appeler. C'est retourner une promesse au lieu de la valeur qui me donne un "type d'accessoire ayant échoué". J'ai pensé à utiliser un état mais je ne pense plus pouvoir appeler la fonction à l'intérieur du composant ListItem.

  getMsg = id => {
    const m = fireStoreDB
      .getUserLastMessage(fireStoreDB.getUID, id)
      .then(msg => {
        return msg;
      });
    return m;
  };

  renderItem = ({ item }) => (
    <ListItem
      onPress={() => {
        this.props.navigation.navigate('Chat', {
          userTo: item.id,
          UserToUsername: item.username
        });
      }}
      title={item.username}
      subtitle={this.getMsg(item.id)} // failed prop type
      bottomDivider
      chevron
    />
  );
-2
CLUTCHER 8 nov. 2019 à 11:35

4 réponses

Vous ne pouvez le faire de cette façon que si ListItem s'attend à voir une promesse pour sa propriété subtitle, ce que je suppose que non. ;-) (Devinez parce que je n'ai pas encore joué avec React Native. React , mais pas React Native.)

Au lieu de cela, le composant devra avoir deux états:

  • Le sous-titre n'est pas encore chargé
  • Le sous-titre est chargé

... et rendre chacun de ces états. Si vous ne voulez pas que le composant ait un état, vous devez alors gérer la requête asynchrone dans le composant parent et rendre uniquement ce composant lorsque vous avez les informations dont il a besoin.

1
T.J. Crowder 8 nov. 2019 à 08:38

Vous pouvez utiliser async et await

getMsg = async (id) => await fireStoreDB.getUserLastMessage(fireStoreDB.getUID, id)
-1
Antoni 8 nov. 2019 à 08:59

Si le «dernier message» est quelque chose de spécifique au seul composant ListItem et pas quelque chose que vous avez déjà sous la main, vous voudrez peut-être laisser l'élément de liste effectuer la demande réseau par lui-même. Je déplacerais la fonction à l'intérieur de ListItem. Vous devrez configurer un état pour conserver cette valeur et éventuellement effectuer un rendu conditionnel. Vous devrez ensuite appeler cette fonction lorsque le composant est monté. Je suppose que vous utilisez des composants fonctionnels, donc useEffect() devrait vous aider ici:

//put this is a library of custom hooks you may want to use
//  this in other places
const useIsMounted = () => {
  const isMounted = useRef(false);
  useEffect(() => {
    isMounted.current = true;
    return () => (isMounted.current = false);
  }, []);
  return isMounted;
};

const ListItem = ({
  title,
  bottomDivider,
  chevron,
  onPress,
  id, //hae to pass id to ListItem
}) => {
  const [lastMessage, setLastMessage] = useState(null);
  const isMounted = useIsMounted();
  React.useEffect(() => {
    async function get() {
      const m = await fireStoreDB.getUserLastMessage(
        fireStoreDB.getUID,
        id
      );
      //before setting state check if component is still mounted
      if (isMounted.current) {
        setLastMessage(m);
      }
    }
    get();
  }, [id, isMounted]);

  return lastMessage ? <Text>DO SOMETHING</Text> : null;
};
0
HMR 8 nov. 2019 à 09:43

La méthode getMsg est asynchrone, vous pouvez procéder comme suit

// if your fireStoreDB.getUserLastMessage return something,you can use like this
getUserLastMessage(id){

    fetch(url) //or query form data
    .then((response){
        return response;
     }).catch((error => { console.log(error)}))
}
getMsg = async (id) => {
        const m = await fireStoreDB.getUserLastMessage(id)
        return m;
      };
// if it return a permise, you should do it more times

Ou vous pouvez réaliser le même effet en utilisant le setState

//firstly you should define the var
this.state ={{
   m:"'
}}

// then update it when the data return
getMsg = id => {
        fireStoreDB
          .getUserLastMessage(fireStoreDB.getUID, id)
          .then(msg => {
            this.setState({
                 m:msg
             })
          }).catch(error => {
               // handle the error
            })
      };
// then use it in the item
...
subTitle = {this.state.m)
...
-1
Lenoarod 8 nov. 2019 à 09:14