V S*_*S X 1 javascript apollo reactjs react-apollo react-hooks
正如我们所知,当 props 或 state 发生变化时,react 组件会重新渲染。
我现在正在使用useQuery从react-apollo包象下面这样:
import { gql, useQuery } from '@apollo/client';
const getBookQuery = gql`
{
books {
name
}
}
`;
function BookList() {
const { loading, error, data} = useQuery(getBookQuery);
if(loading) return <p>Loading....</p>
if(error) return <p>Ops! Something went wrong</p>
return (
<>
<ul>
{data.books.map(book => (
<li key={book.name}>{book.name}</li>
))}
</ul>
</>
)
}
export default BookList;
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,我们首先进入Loading...DOM,然后将其更新为包含查询数据的列表(一旦它到达)。但是一旦从查询中收到数据,react 如何知道重新渲染我的组件。
这些data,loading和error属性是否映射到组件 props 并且它们正在更新?如果是这样,为什么 chrome 开发工具不显示此BookList组件的任何道具?
有人可以解释一下这个useQuery自定义钩子是如何在这里工作的吗?
弄清楚(大致)正在发生的事情的一个好方法useQuery是考虑如何自己做,例如
const MyComponent = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(async () => {
try {
setLoading(true);
const data = await GraphQL.request(getBookQuery);
setData(data);
} catch (ex) {
setError(ex);
} finally {
setLoading(false);
}
}, []);
if(loading) return <p>Loading....</p>
if(error) return <p>Ops! Something went wrong</p>
return (
<>
<ul>
{data.books.map(book => (
<li key={book.name}>{book.name}</li>
))}
</ul>
</>
);
};
Run Code Online (Sandbox Code Playgroud)
在上面你可以看到你的组件有状态(没有道具)data,loading而error这将导致您的组件重新呈现。
然后你可以想象这个逻辑被包裹在你自己的useQuery钩子中:
const useQuery = (query, variables) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(async () => {
try {
setLoading(true);
const data = await GraphQL.request(query, variables);
setData(data);
} catch (ex) {
setError(ex);
} finally {
setLoading(false);
}
}, []);
return { data, loading, error };
}
const MyComponent = () => {
const { data, loading, error } = useQuery(getBookQuery);
if(loading) return <p>Loading....</p>
if(error) return <p>Ops! Something went wrong</p>
return (
<>
<ul>
{data.books.map(book => (
<li key={book.name}>{book.name}</li>
))}
</ul>
</>
);
};
Run Code Online (Sandbox Code Playgroud)
所以最终你的组件正在重新渲染,因为它确实有data,loading并且error保持在MyComponent状态中,它只是被抽象掉了。
| 归档时间: |
|
| 查看次数: |
1549 次 |
| 最近记录: |