我正在构建一个不和谐/松弛的克隆。我有渠道、消息和用户。一旦我的聊天组件加载,频道就会通过useQuery钩子从Apollo获取。
默认情况下,当用户来到聊天组件时,他需要单击特定的频道来查看关于该频道的信息和消息。
在较小的Channel.js组件中,我将单击的Channel的通道In写入apollo缓存。这非常好用,我在Messages.js组件中使用了useQuery钩子@client来从缓存中获取通道it,它工作得很好。
当我使用useLazyQuery钩子来获取特定通道(用户单击的通道)的消息时,问题就出现了。
它会在React中导致无限的重新渲染循环,导致应用程序崩溃。
我尝试过使用带有跳过选项的普通useQuery钩子。然后,我会在需要时调用refetch()函数。这在某种意义上说是“有效”的,因为它不会给我无限循环。但是console.log()给了我这个错误:[GraphQL error]: Message: Variable "$channelid" of required type "String!" was not provided. Path: undefined。这很奇怪,因为我的模式和变量是正确的??
正如前面所说的,useLazyQuery确实给了我无限循环。
我真的很纠结于apollo/react钩子的条件性...
/ Channel.js组件/
const Channel = ({ id, channelName, channelDescription, authorName }) => {
const chatContext = useContext(ChatContext);
const client = useApolloClient();
const { fetchChannelInfo, setCurrentChannel } = chatContext;
const selectChannel = (e, id) => {
fetchChannelInfo(true);
const currentChannel = {
channelid: id,
channelName,
channelDescription,
authorName
};
setCurrentChannel(currentChannel);
client.writeData({
data: {
channelid: id
}
});
// console.log(currentChannel);
};
return (
<ChannelNameAndLogo onClick={e => selectChannel(e, id)}>
<ChannelLogo className='fab fa-slack-hash' />
<ChannelName>{channelName}</ChannelName>
</ChannelNameAndLogo>
);
};
export default Channel;/ Messages.js组件/
const FETCH_CHANNELID = gql`
{
channelid @client
}
`;
const Messages = () => {
const [messageContent, setMessageContent] = useState('');
const chatContext = useContext(ChatContext);
const { currentChannel } = chatContext;
// const { data, loading, refetch } = useQuery(FETCH_MESSAGES, {
// skip: true
// });
const { data: channelidData, loading: channelidLoading } = useQuery(
FETCH_CHANNELID
);
const [fetchMessages, { data, called, loading, error }] = useLazyQuery(
FETCH_MESSAGES
);
//// useMutation is working
const [
createMessage,
{ data: MessageData, loading: MessageLoading }
] = useMutation(CREATE_MESSAGE);
if (channelidLoading && !channelidData) {
console.log('loading');
setInterval(() => {
console.log('loading ...');
}, 1000);
} else if (!channelidLoading && channelidData) {
console.log('not loading anymore...');
console.log(channelidData.channelid);
fetchMessages({ variables: { channelid: channelidData.channelid } });
console.log(data);
}我希望有来自useLazyQuery ...But的数据中的消息,而不是在console.log()中获得以下内容:
react-dom.development.js:16408 Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop.
发布于 2019-09-11 14:14:20
您可以在每次渲染时调用fetchMessages。尝试将fetchMessages放在useEffect中:
useEffect(() => {
if (!channelidLoading && channelidData) {
fetchMessages();
}
}, [channelidLoading, channelidData]);与此类似,只有在channelidLoading或channelidData发生变化时才调用fetchMessages函数。
发布于 2020-01-02 17:14:29
您可以使用useLazyQuery返回的called变量。
!called && fetchMessages({ variables: { channelid: channelidData.channelid } });
发布于 2020-02-13 01:02:40
您还可以考虑执行以下操作:
import debounce from 'lodash.debounce';
...
const [fetchMessages, { data, called, loading, error }] = useLazyQuery(
FETCH_MESSAGES
);
const findMessageButChill = debounce(fetchMessages, 350);
...
} else if (!channelidLoading && channelidData) {
findMessageButChill({
variables: { channelid: channelidData.channelid },
});
}https://stackoverflow.com/questions/57784602
复制相似问题