Wes*_*ton 3 javascript apollo reactjs graphql
所以看看文档中的 Apollo useMutation 示例https://www.apollographql.com/docs/react/data/mutations/#tracking-loading-and-error-states
function Todos() {
...
const [
updateTodo,
{ loading: mutationLoading, error: mutationError },
] = useMutation(UPDATE_TODO);
...
return data.todos.map(({ id, type }) => {
let input;
return (
<div key={id}>
<p>{type}</p>
<form
onSubmit={e => {
e.preventDefault();
updateTodo({ variables: { id, type: input.value } });
input.value = '';
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Update Todo</button>
</form>
{mutationLoading && <p>Loading...</p>}
{mutationError && <p>Error :( Please try again</p>}
</div>
);
});
}
Run Code Online (Sandbox Code Playgroud)
这似乎有一个重大缺陷(imo),更新任何待办事项都会显示每个待办事项的加载状态,而不仅仅是具有待处理突变的待办事项。
这似乎源于一个更大的问题:无法跟踪对同一突变的多次调用的状态。因此,即使我确实只想显示实际加载的待办事项的加载状态,也没有办法做到这一点,因为我们只有“正在加载”的概念,而不是“正在为待办事项 X 加载”的概念。
除了在 Apollo 之外手动跟踪加载状态之外,我能看到的唯一合适的解决方案是拆分一个单独的组件,使用它来呈现每个 Todo,而不是直接在 Todos 组件中使用该代码,并让这些组件各自初始化自己的突变。我不确定我认为这是一个好还是坏的设计,但在任何一种情况下,我都不觉得我应该改变组件的结构来实现这一点。
这也扩展到错误处理。如果我更新一个待办事项,然后在第一个更新正在进行时更新另一个会怎样。如果第一次调用出错,那在data返回的 from 中useMutation是否可见?第二个电话呢?
有没有原生的 Apollo 方法来解决这个问题?如果没有,是否有比我提到的更好的处理方法?
诚然,应该重写文档中的示例以使其更加清晰。它还存在许多其他问题。
的useQuery和useMutation挂钩仅设计用于在时间跟踪单个操作的装载,错误和结果状态。操作的变量可能会改变,可能会重新获取或附加到 using fetchMore,但最终,您仍然只是在处理那个操作。您不能使用单个钩子来跟踪多个操作的单独状态。为此,您需要多个钩子。
对于这样的表单,如果提前知道输入字段,那么您可以将钩子拆分为同一组件中的多个:
const [updateA, { loading: loadingA, error: errorA }] = useMutation(YOUR_MUTATION)
const [updateB, { loading: loadingB, error: errorB }] = useMutation(YOUR_MUTATION)
const [updateC, { loading: loadingC, error: errorC }] = useMutation(YOUR_MUTATION)
Run Code Online (Sandbox Code Playgroud)
如果您正在处理可变数量的字段,那么我们必须将此逻辑分解为一个单独的逻辑,因为我们无法在循环中声明钩子。这不是 Apollo API 的限制,而只是钩子本身背后的魔法的副作用。
const ToDo = ({ id, type }) => {
const [value, setValue] = useState('')
const options = { variables = { id, type: value } }
const const [updateTodo, { loading, error }] = useMutation(UPDATE_TODO, options)
const handleChange = event => setValue(event.target.value)
return (
<div>
<p>{type}</p>
<form onSubmit={updateTodo}>
<input
value={value}
onChange={handleChange}
/>
<button type="submit">Update Todo</button>
</form>
</div>
)
}
// back in our original component...
return data.todos.map(({ id, type }) => (
<Todo key={id} id={id} type={type] />
))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3330 次 |
| 最近记录: |