如何在反应组件(打字稿+ css)中使用向上和向下键切换div焦点
Posted
技术标签:
【中文标题】如何在反应组件(打字稿+ css)中使用向上和向下键切换div焦点【英文标题】:How to toggle div focus using up and down key in react component (typescript + css) 【发布时间】:2021-08-28 10:53:49 【问题描述】:我在各种 div 中呈现数据,我想在用户按下向上/向下箭头时选择/聚焦 div。
对于使用向上/向下键选择 div,我看到使用 ref 和 ForewardRef 作为子组件,我们可以切换焦点,但仍在努力弄清楚如何在打字稿代码中实现这一点。
我对此反应不熟悉,因此欢迎对以下代码提出任何建议或改进。
下面是我的代码。
选项.ts
export interface option
id:number;
label:string;
value:string;
App.tsx
import React, useRef, useEffect from 'react';
import option from './option';
import Options from './options';
export default function App()
const options : option[] = [
id:0, label : "Option 1", value:"12000",
id:1, label : "Option 2", value:"10000" ,
id:2, label : "Option 3", value:"11000",
id:3, label : "Option 4", value:"23000"
];
const [invTheme, setInvTheme] = React.useState("10000");
const firstRef = React.createRef<htmlDivElement>();
const checkedRef = React.createRef<HTMLDivElement>();
useEffect(() =>
if (checkedRef.current)
checkedRef.current.focus();
else if (firstRef.current)
firstRef.current.focus();
, []);
return (
<div className="App">
options.map((option, i) =>
const id, label, value = option;
const checked = invTheme === value;
return (
<div key=i>
<Options id=id label=label value=value checked=checked
onChange=() =>
setInvTheme(value);
/>
<br></br>
</div>
)
)
</div>
);
Options.tsx
import React, useEffect from 'react'
import makeStyles, createStyles, Theme from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
const useStyles = makeStyles((theme: Theme) =>
createStyles(
root:
flexGrow: 1,
,
div:
padding: theme.spacing(2),
margin: 'auto',
maxWidth: 700,
border:`1px solid Gray`
,
selectedDiv:
padding: theme.spacing(2),
margin: 'auto',
maxWidth: 700,
border: `2px solid Blue`
),);
export default function Options(props:any)
const classes = useStyles();
//const [selectedDiv, setSelectedDiv] = React.useState(false);
//useEffect(()=>
//if(checked) setSelectedDiv(true);
//,[])
const handleOnClick = (e:any) =>
if (e.type === "click" && e.clientX !== 0 && e.clientY !== 0)
//setSelectedDiv(true);
onChange(target:value);
;
const id, label, value, onChange, checked = props;
console.log("id: "+ id+" checked "+ checked);
return (
<div>
<div className=checked ? classes.selectedDiv : classes.div onClick=handleOnClick>
<Grid container spacing=2>
<Grid item>
<input id=id type="radio" name="type" aria-label=label checked=checked value=value onChange=onChange/>
</Grid>
<Grid item >
label
</Grid>
</Grid>
</div>
</div>
);
【问题讨论】:
【参考方案1】:我就是这样解决的。
我利用checked props来控制div的style属性。
在代码下方找到:
options.tsx:
import React, useEffect from 'react'
import makeStyles, createStyles, Theme from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
const useStyles = makeStyles((theme: Theme) =>
createStyles(
root:
flexGrow: 1,
,
div:
padding: theme.spacing(2),
margin: 'auto',
maxWidth: 700,
border:`1px solid Gray`,
,
selectedDiv:
padding: theme.spacing(2),
margin: 'auto',
maxWidth: 700,
border:`1px solid Gray`,
,
selected:
),);
export default function Options(props:any)
const classes = useStyles();
const [selectedDiv, setSelectedDiv] = React.useState(false);
const id, label, selected, value, onChange, checked = props;
useEffect(()=>
if(selected) setSelectedDiv(true);
,[])
const handleOnClick = (e:any) =>
if (e.type === "click" && e.clientX !== 0 && e.clientY !== 0)
setSelectedDiv(true);
onChange(target:value);
;
return (
<div>
<div className=selectedDiv ? classes.selectedDiv :classes.div onClick=handleOnClickstyle = checked && selectedDiv? border: `2px solid Blue`,maxWidth: 700,: >
<Grid container spacing=2 >
<Grid item>
<input id=id type="radio" name="type" aria-label=label checked=checked value=value onChange=onChange/>
</Grid>
<Grid item >
label
</Grid>
</Grid>
</div>
</div>
);
App.tsx:
import React, useRef, useEffect from 'react';
import option from './option';
import Options from './options'
export default function App()
const options : option[] = [
id:0, label : "Option 1", selected : false, value:"12000",
id:1, label : "Option 2", selected : true, value:"10,000" ,
id:2, label : "Option 3", selected : false, value:"10000",
id:3, label : "Option 4", selected : false, value:"23000"
];
const [invTheme, setInvTheme] = React.useState("12000");
const firstRef = React.createRef<HTMLDivElement>();
const checkedRef = React.createRef<HTMLDivElement>();
useEffect(() =>
if (checkedRef.current)
checkedRef.current.focus();
else if (firstRef.current)
firstRef.current.focus();
, []);
return (
<div className="App">
options.map((option, i) =>
const id, label, selected, value = option;
const checked = invTheme === value;
return (
<div key=i >
<Options id=id label=label selected=selected value=value checked=checked
onChange=() =>
setInvTheme(value);
/>
<br></br>
</div>
)
)
</div>
);
【讨论】:
感谢您的样式条件输入,我得到了修改类条件并获得突出显示的 div 的想法。我已经更新了我想要实现的第二个问题的问题。以上是关于如何在反应组件(打字稿+ css)中使用向上和向下键切换div焦点的主要内容,如果未能解决你的问题,请参考以下文章