reactjs - 我可以忽略 useContext 的详尽警告吗?
问题描述
在我的 react-typescript 应用程序中,我正在尝试使用一个上下文提供程序来封装属性和方法并将它们公开给消费者:
const StockPriceConsumer: React.FC = () => {
const stockPrice = useContext(myContext);
let val = stockPrice.val;
useEffect(() => {
stockPrice.fetch();
}, [val]);
return <h1>{val}</h1>;
};
问题是以下警告:
React Hook useEffect 缺少依赖项:'stockPrice'。包括它或删除依赖数组。eslint(react-hooks/exhaustive-deps)
stockPrice
对我来说,将(基本上是提供者的 API)包含到 useEffect 的依赖项中没有任何意义。只有包含股票价格的实际价值以防止无限调用 useEffect 函数才有意义。
问题:我尝试使用的方法有什么问题,或者我可以忽略这个警告吗?
提供者:
interface StockPrice {
val: number;
fetch: () => void;
}
const initialStockPrice = {val: NaN, fetch: () => {}};
type Action = {
type: string;
payload: any;
};
const stockPriceReducer = (state: StockPrice, action: Action): StockPrice => {
if (action.type === 'fetch') {
return {...state, val: action.payload};
}
return {...state};
};
const myContext = React.createContext<StockPrice>(initialStockPrice);
const StockPriceProvider: React.FC = ({children}) => {
const [state, dispatch] = React.useReducer(stockPriceReducer, initialStockPrice);
const contextVal = {
...state,
fetch: (): void => {
setTimeout(() => {
dispatch({type: 'fetch', payload: 200});
}, 200);
},
};
return <myContext.Provider value={contextVal}>{children}</myContext.Provider>;
};
解决方案
我建议从提供者控制整个获取逻辑:
const StockPriceProvider = ({children}) => {
const [price, setPrice] = React.useState(NaN);
useEffect(() => {
const fetchPrice = () => {
window.fetch('http...')
.then(response => response.json())
.then(data => setPrice(data.price))
}
const intervalId = setInterval(fetchPrice, 200)
return () => clearInterval(intervalId)
}, [])
return <myContext.Provider value={price}>{children}</myContext.Provider>;
};
const StockPriceConsumer = () => {
const stockPrice = useContext(myContext);
return <h1>{stockPrice}</h1>;
};
...作为原始方法中几个问题的解决方案:
- 你真的想只取
val
不同的东西吗?如果 2 次渲染之间的股票价格相同,则不会执行 useEffect。 fetch
每次<StockPriceProvider>
渲染都需要创建一个新方法吗?这确实不适合 useEffect 的依赖关系。- 如果两者都可以,请随意禁用 eslint 警告
- 如果您想在安装了消费者后以 200 毫秒的间隔继续获取:
// StockPriceProvider
...
fetch: useCallback(() => dispatch({type: 'fetch', payload: 200}), [])
...
// StockPriceConsumer
...
useEffect(() => {
const i = setInterval(fetch, 200)
return () => clearInterval(i)
}, [fetch])
...
推荐阅读
- c - 为什么我的函数收到未在此范围内定义的错误?我只是想调用该函数并让它立即运行
- r - R中的projectRaster函数耗尽了矢量内存
- c - 如何解决“距离未打印在显示器上”?
- java - 任务已安排或取消
- android - 如何使用 LOOKUP KEY 在 android 中检索联系人的详细联系信息?
- docker - 没有找到Circleci Jest?
- reactjs - 我们可以使用功能组件并与 ag-grid 表反应挂钩吗?
- vue.js - 你如何在 Laravel+Vue 中设置 css-loader?
- javascript - 如何从渲染方法之外的反应导航中获取导航参数?
- python - 为什么添加两个具有 timedelta 值的计数器会引发 TypeError?