繁体   English   中英

如何将 promise 中的值传递给 react native 的组件 prop?

[英]How do I pass a value from a promise to a component prop in react native?

编辑:我不明白投反对票的原因,这是一个很好的问题,这个网站上没有其他问题解决了我的问题。 我只是预先加载了数据来解决我的问题,但如果不使用功能组件,这仍然无法解决问题。

我正在尝试将用户最后一条消息传递给 ListItem 字幕道具,但我似乎无法找到从承诺/然后调用返回值的方法。 它返回 promise 而不是给我“失败的道具类型”的值。 我考虑过使用 state 但后来我认为我不能再在 ListItem 组件中调用 function 了。

  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
    />
  );

如果ListItem期望看到 promise 的subtitle属性,你只能这样做,我猜它不会。 ;-)(猜测是因为我还没有玩过 React Native。 React ,但不是 React Native。)

相反,组件需要有两种状态:

  • 字幕还没加载
  • 字幕已加载

...并渲染每个状态。 如果您不希望该组件具有 state,那么您需要在父组件中处理异步查询,并且仅在您拥有该组件所需的信息时才呈现组件。

如果“最后一条消息”是特定于ListItem组件的内容,而不是您手头已有的内容,您可能希望让列表项自己发出网络请求。 我会将 function 移动到ListItem内。 您需要设置一些 state 来保存此值,并可能进行一些条件渲染。 然后您需要在安装组件时调用此 function。 我假设您正在使用功能组件,所以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;
};

我通过在另一个 promise 方法中使用该 promise 方法解决了这个问题,该方法是我在 componentDidMount 上拥有的,并将用户的最后一条消息添加为所有用户的额外字段。 这样我就可以在一个 state 中拥有所有用户信息来填充 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
    />
  );

getMsg 方法是异步的,您可以执行以下操作,因为 HMR 说等待仍然返回 promise,在我阅读了一篇文章( https://medium.com/dailyjs/javascript-promises-zero-to-hero- plus-cheat-sheet-64d75051cfa ),并做一些实验。 promise 可以返回值。

fetchData = () => {
  return new Promise((resolve, reject) => {
  setTimeout(function() {
    resoleve(2)
  }, 300);
}).then(() => {
  return 3
});
}

let a = await this.fetchData()
alert(a);

a 为 3。您可以继续在调用方法中处理响应。如以下代码。如果它不返回值。 我认为fireStoreDB.getUserLastMessage(id)不返回任何内容。

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

或者您可以使用 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)
...

你可以使用asyncawait

getMsg = async (id) => await fireStoreDB.getUserLastMessage(fireStoreDB.getUID, id)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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