Как передать значение из обещания компоненту prop в реагировать на натив? - PullRequest
0 голосов
/ 08 ноября 2019

Редактировать: Я не понимаю причину отрицательных голосов, это был хороший вопрос, и никакие другие вопросы на этом сайте не решили мою проблему. Я просто предварительно загрузил данные, чтобы решить мою проблему, но это все равно не решило проблему без использования функциональных компонентов.

Я пытаюсь передать последнее сообщение пользователей в подпункт субтитров ListItem, но не могунайти способ вернуть значение из обещания / затем позвонить. Он возвращает обещание вместо значения, которое дает мне «проваленный тип пропа». Я думал об использовании состояния, но потом не думаю, что смогу больше вызывать функцию внутри компонента 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
    />
  );

Ответы [ 3 ]

3 голосов
/ 08 ноября 2019

Вы могли бы сделать это таким образом, только если ListItem ожидал увидеть обещание для его свойства subtitle, что, я полагаю, не дает. ;-) (Догадываюсь, потому что я еще не играл с React Native. React , но не React Native.)

Вместо этого компонент должен иметь два состояния:

  • Субтитры еще не загружены
  • Субтитры загружены

... и отображают каждое из этих состояний. Если вы не хотите, чтобы компонент имел состояние, то вам нужно обработать асинхронный запрос в родительском компоненте и отображать этот компонент только тогда, когда у вас есть необходимая информация.

0 голосов
/ 08 ноября 2019

Я исправил проблему, используя этот метод обещания в другом методе обещания, который я использовал в componentDidMount, и добавил последнее сообщение пользователя в качестве дополнительного поля для всех пользователей. Таким образом, у меня есть информация обо всех пользователях в одном состоянии для заполнения ListItem.

  componentDidMount() {
    fireStoreDB
      .getAllUsersExceptCurrent()
      .then(users =>
        Promise.all(
          users.map(({ id, username }) =>
            fireStoreDB
              .getUserLastMessage(fireStoreDB.getUID, id)
              .then(message => ({ id, username, message }))
          )
        )
      )
      .then(usersInfo => {
        this.setState({ usersInfo });
      });
  }

  renderItem = ({ item }) => (
    <ListItem
      onPress={() => {
        this.props.navigation.navigate('Chat', {
          userTo: item.id,
          UserToUsername: item.username
        });
      }}
      title={item.username}
      subtitle={item.message}
      bottomDivider
      chevron
    />
  );
0 голосов
/ 08 ноября 2019

Если «последнее сообщение» относится только к компоненту ListItem, а не к тому, что у вас уже есть, вы можете разрешить элементу списка выполнять сетевой запрос самостоятельно. Я бы переместил функцию внутрь ListItem. Вам нужно установить какое-то состояние для хранения этого значения и, возможно, выполнить условный рендеринг. Затем вам нужно будет вызвать эту функцию, когда компонент смонтирован. Я предполагаю, что вы используете функциональные компоненты, поэтому useEffect() должен помочь вам здесь:

//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;
};
...