Reactjs TypeScript媒体查询
我正在尝试将原始的“.js”媒体查询转换为“.ts”。我原来的实用程序很容易转换:Reactjs TypeScript媒体查询,reactjs,typescript,Reactjs,Typescript,我正在尝试将原始的“.js”媒体查询转换为“.ts”。我原来的实用程序很容易转换: const min = (width: number) => `only screen and (min-width: ${width}em)` const max = (width: number) => `only screen and (max-width: ${width}em)` // The screen widths in em units. export const screens
const min = (width: number) => `only screen and (min-width: ${width}em)`
const max = (width: number) => `only screen and (max-width: ${width}em)`
// The screen widths in em units.
export const screens = {
phone: 30,
phablet: 40,
tablet: 50,
netbook: 60,
laptop: 70,
desktop: 100,
}
export const mediaQueries = Object.entries( screens )
.reduce<Record<string, string | number>>(
( acc, [key, val] ) => {
const Key = key[0].toUpperCase() + key.substr( 1 )
// css query
acc[`min` + Key] = `@media ` + min( val )
acc[`max` + Key] = `@media ` + max( val )
// js query (see window.matchMedia)
acc[`min` + Key + `Js`] = min( val )
acc[`max` + Key + `Js`] = max( val )
return acc
}, {}
)
const min=(宽度:number)=>`仅屏幕和(最小宽度:${width}em)`
const max=(宽度:number)=>`仅屏幕和(最大宽度:${width}em)`
//屏幕宽度以em为单位。
导出常量屏幕={
电话:30,
法布雷特:40,
片剂:50,
上网本:60,
笔记本电脑:70,
桌面:100,
}
export const mediaQueries=Object.entries(屏幕)
.减少(
(acc,[key,val])=>{
常量键=键[0]。toUpperCase()+Key.substr(1)
//css查询
acc[`min`+Key]=`@media`+min(val)
acc[`max`+Key]=`@media`+max(val)
//js查询(参见window.matchMedia)
acc[`min`+Key+`Js`]=min(val)
acc[`max`+Key+`Js`]=max(val)
返回acc
}, {}
)
React钩子访问媒体查询时遇到困难。这就是我得到的错误:
“string | number”类型的参数不能分配给“string”类型的参数。
类型“number”不可分配给类型“string”。ts(2345)
从'react'导入{useffect,useState}
从“../utils/mediaQueries”导入{mediaQueries}
接口myCallbackType{(myArgument:string):void}
export const useMediaQuery=(查询:字符串,cb:myCallbackType)=>{
const[matches,setMatches]=useState(false)
useffect(()=>{
const qry=window.matchMedia(查询)
setMatches(qry.matches)
const handleMatch=(q:any)=>{
setMatches(q.matches)
if(cb instanceof函数)cb(q.matches)
}
qry.addListener(handleMatch)
return()=>qry.removeListener(handleMatch)
},[query,cb])
复赛
}
const validKeys=Object.key(mediaquerys.filter)(
key=>!key.includes(`Js`)
)
导出常量useScreenQuery=(键:字符串,cb:myCallbackType)=>{
如果(!mediaQueries[key+`Js`])
抛出新类型错误(
`useScreenQuery收到无效密钥:${key}`
+`应该是${validKeys}中的一个`
)
返回useMediaQuery(
mediaQueries[key+`Js`],/useMediaQuery
需要字符串,但是mediaQueries
元素可以是数字。您能否更新useMediaQuery
以使用string | number
进行查询?否则,您必须强制转换或检查它是否是字符串。避免acc
的变异。使用{…acc,[prop]:'some value'}
import { useEffect, useState } from 'react'
import { mediaQueries } from '../utils/mediaQueries'
interface myCallbackType { (myArgument: string): void }
export const useMediaQuery = ( query: string, cb: myCallbackType ) => {
const [matches, setMatches] = useState( false )
useEffect( () => {
const qry = window.matchMedia( query )
setMatches( qry.matches )
const handleMatch = ( q: any) => {
setMatches( q.matches )
if ( cb instanceof Function ) cb( q.matches )
}
qry.addListener( handleMatch )
return () => qry.removeListener( handleMatch )
}, [query, cb] )
return matches
}
const validKeys = Object.keys( mediaQueries ).filter(
key => !key.includes( `Js` )
)
export const useScreenQuery = ( key: string, cb: myCallbackType ) => {
if ( !mediaQueries[key + `Js`] )
throw new TypeError(
`useScreenQuery received an invalid key: ${key}.`
+ ` Should be one of ${validKeys}`
)
return useMediaQuery(
mediaQueries[key + `Js`], // <- Error here
cb
)
}