从 graphql useQuery 检索的数据未显示在子组件中,但在 state 和 props 中可用

Data retrieved from graphql useQuery not displaying in child component but is available in the state and props

我遇到了一个问题,这可能仅仅是因为我对 graphql 和 React 渲染方法的理解有限。话虽如此,我希望有人能提供帮助。

我有一个带有 USERS 和 USER 组件的简单应用。

我使用 Apollo useQuery 挂钩在 USERS 应用程序中检索数据。然后我通过直接将数据添加为 props 和 useState 将数据传递给 USER 组件。
当我访问 Chrome 和 Apollo Developer 工具时,我可以看到道具和状态数据是正确的。
但是 USER 组件中的 Textfield 显示空数据。
USERS 组件中的 Textfield 显示正常。

USERS.js

export default function Users() {
  const [UserInfo, setUserInfo] = useState({});
  const { loading, error, data } = useQuery(USER_DATA);
  const { register, watch, handleSubmit, control, reset, errors } = useForm();

  useEffect(() => {
    // if (data) {
    //   const { id, name, username } = data.users.data[0];
    //   setUserInfo({ id, name, username });
    // }

    if (loading === false && data) {
      setUserInfo(data.users.data[0]);
    }
  }, [loading, data]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <>
      <h1>Hi there</h1>
      {console.log(data)}
      {/* User component */}

      <div style={{ border: "10px solid green", padding: "5px" }}>
        <h3>From the USERS Component</h3>
        <Controller
          as={TextField}
          variant="outlined"
          required
          fullWidth
          id="firstName"
          label="First Name"
          name="firstName"
          autoComplete="fname"
          control={control}
          rules={{ required: true }}
          defaultValue={data.users.data[0].name}
          margin="dense"
        />
        <TextField
          fullWidth
          label="First Name"
          variant="outlined"
          margin="dense"
          value={UserInfo.name}
        />
        <div style={{ border: "10px solid red", padding: "5px" }}>
          <User
            id={data.users.data[0].id}
            UserInfo={UserInfo}
            name={data.users.data[0].name}
            username={data.users.data[0].username}
          />
        </div>
      </div>
    </>
  );
}

User.js

export default function User({id, UserInfo, name, username}) {
  const { register, watch, handleSubmit, control, reset, errors } = useForm();

  return (
    <div>
      <h3>From the User Component</h3>
      <TextField
        id="standard-required"
        fullWidth
        label="Required"
        value={UserInfo.name}
        variant="outlined"
        margin="dense"
      />
    </div>
  );
}

我做错了什么?

此处提供 CODESANDBOX:Codesandbox

所以我最终不得不在 USERS 组件中添加条件语句以使其工作。这是否是最佳解决方案还有待商榷。如果有更好的解决方案,请告诉我。

更新代码:

USERS.js

export default function Users() {
  const [UserInfo, setUserInfo] = useState(undefined);
  const { loading, error, data } = useQuery(USER_DATA);
  const { register, watch, handleSubmit, control, reset, errors } = useForm();

  useEffect(() => {
    // if (data) {
    //   const { id, name, username } = data.users.data[0];
    //   setUserInfo({ id, name, username });
    // }

    if (loading === false && data) {
      setUserInfo(data.users.data[0]);
    }
  }, [loading, data]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <>
      <h1>Hi there</h1>
      {console.log(data)}
      {/* User component */}

      <div style={{ border: "10px solid green", padding: "5px" }}>
        <h3>From the USERS Component</h3>
        <Controller
          as={TextField}
          variant="outlined"
          required
          fullWidth
          id="firstName"
          label="First Name"
          name="firstName"
          autoComplete="fname"
          control={control}
          rules={{ required: true }}
          defaultValue={data.users.data[0].name}
          margin="dense"
        />
        <div style={{ border: "10px solid red", padding: "5px" }}>
          {/* ===== ADDED THE CONDITIONAL BELOW ===== */}
          {UserInfo !== undefined ? (
            <User
              id={data.users.data[0].id}
              UserInfo={UserInfo}
              name={data.users.data[0].name}
              username={data.users.data[0].username}
            />
          ) : null}
        </div>
      </div>
    </>
  );
}

USER.js

export default function User({ id, UserInfo, name, username }) {
  const { register, watch, handleSubmit, control, reset, errors } = useForm();

  return (
    <div>
      <h3>From the User Component</h3>
      <TextField
        id="standard-required"
        fullWidth
        label="Required"
        value={UserInfo.name}
        variant="outlined"
        margin="dense"
      />
   
    </div>
  );
}