![](/img/trans.png)
[英]How do I pass a Prop to a Navigation Screen Component - React Native
[英]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)
...
你可以使用async
和await
getMsg = async (id) => await fireStoreDB.getUserLastMessage(fireStoreDB.getUID, id)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.