Javascript GraphQL默认数据会导致useEffect中的无限循环

Javascript GraphQL默认数据会导致useEffect中的无限循环,javascript,reactjs,typescript,graphql,react-hooks,Javascript,Reactjs,Typescript,Graphql,React Hooks,所以我有这个密码 const [localState, setLocalState] = useState<StateType[]>([]); const { data = { attribute: [] }, loading } = useQuery<DataType>(QUERY, { variables: { id: client && client.id }, skip: user.clients && user

所以我有这个密码

const [localState, setLocalState] = useState<StateType[]>([]);
const { data = { attribute: [] }, loading } = useQuery<DataType>(QUERY, {
  variables: {
    id: client && client.id
  },
  skip: user.clients && user.clients.length === 0
});

useEffect(() => {
  if (loading || !data) {
    return undefined;
  }

  if (data && data.attribute) {
    const sortedResult = data.attribute.sort((a, b) =>
      a.updatedAt < b.updatedAt ? 1 : -1
    );
    setLocalState(sortedResult);
  }
}, [data]);
为什么useQuery中的默认参数使useEffect被无限触发?


(需要添加的重要注意事项-我试图删除排序函数,认为它会变异数据对象并导致重新输入,但它没有改变任何内容)

您的
数据在每次渲染时都是一个新对象,例如重新触发重新触发渲染的
useffect
,等等

我认为您不需要
useffect
这里:

const{data,load}=useQuery<
数据类型
>(质询{
变量:{
id:(客户端和客户端id)
},
跳过:user.clients&&user.clients.length==0
});
const localState=(!加载&&data&&data.attribute)
? 未定义
:data.attribute.sort(
(a,b)=>(a.updatedAt
应该足够了

const{data={attribute:[]},load}=useQuery(QUERY,{

这个声明没有更大的意义:

  • 不需要,因为所有渲染[和计算]都应该(并且已经)被
    数据阻止
    首先检查
  • 更深层的嵌套值是什么?下一个空声明?它会导致死胡同
它可以在每次渲染时创建一个新的
数据
对象…但它不应该导致无限次的重新渲染…还有其他原因吗

可以通过以下方式打破效果循环:

const [localState, setLocalState] = useState(null);

useEffect(() => {
  if (data && data.attribute && !localState) {
您还可以在钩子中使用
onCompleted
事件:

const { loading } = useQuery<DataType>(QUERY, {
  variables: {
    id: client && client.id
  },
  skip: user.clients && user.clients.length === 0
  onCompleted: (data) => {
    if(data && data.attribute) {
      const sortedResult = data.attribute.sort((a, b) =>
        a.updatedAt < b.updatedAt ? 1 : -1
      );
      setLocalState(sortedResult);
    }
  }
});
const{loading}=useQuery(查询{
变量:{
id:client&&client.id
},
跳过:user.clients&&user.clients.length==0
未完成:(数据)=>{
if(数据和数据属性){
const sortedResult=data.attribute.sort((a,b)=>
a、 updatedAt

…检查/使用
加载
{localState&&}

但是如果我不使用
useffect
在useQuery的承诺成功返回后,localState将不会更新。同样,根据我的理解,没有状态的UI也不会重新呈现。@valentinIvanov您已经在重新呈现(在
数据
更改之后),不需要额外的重新提交(状态更改后)我不认为这是在数据更改后重新提交,来自graphql文档()默认情况下,
notifyOnNetworkStatusChange
设置为false,我在代码中的任何地方都没有将其设置为true。
notifyOnNetworkStatusChange
不同,您尝试了代码吗?
useQuery
将重新渲染,或者您将不会有循环。这是比我更好的解决方案,谢谢。但我是否可以使用默认值的问题是像useQuery的spread操作符中的so
={attribute:[]}
之类的参数,或者这是一种不好的行为仍然困扰着我。只是想知道,为了将来的使用,你应该避免这种声明…YAGNI
const { loading } = useQuery<DataType>(QUERY, {
  variables: {
    id: client && client.id
  },
  skip: user.clients && user.clients.length === 0
  onCompleted: (data) => {
    if(data && data.attribute) {
      const sortedResult = data.attribute.sort((a, b) =>
        a.updatedAt < b.updatedAt ? 1 : -1
      );
      setLocalState(sortedResult);
    }
  }
});