javascript - Hvordan refererer jeg til dokumentet i React TypeScript?
Jeg vil gjøre dette i en av mine betingede funksjoner, men det gir fullstendig feil. Selv om jeg tildeler det til en variabel, sier det "kan ikke finne navnerommet 'document'"
document.getElementById("dropdown").selectedIndex = "1";
Og når jeg setter det inn i funksjonen min, sier det at objektet muligens er null, så hvordan refererer jeg til dette i en React TSX-fil?
Jeg har en select-setning som jeg trenger å dynamisk velge standardverdien for basert på noen betingelser. Hvis disse betingelsene er sanne, vil den kjøre denne dokumentvelgeren for å velge indeksen til den spesifiserte verdien. Jeg trenger bare å finne en måte å kjøre en funksjon som velger standardverdien for denne select-setningen, det er målet mitt.
<Select
value={action}
variant="outlined"
classes={{ select: classes.selectOutlined }}
id="dropdown"
displayEmpty
inputProps={{ 'aria-label': 'Action' }}
onChange={(event) => handleActionChange(event.target.value as string)}
>
<MenuItem value="Action" disabled>
Choose an Action
</MenuItem>
{actions.map((action) => {
return <MenuItem key={action.text} value={action.text}>{action.text}</MenuItem>
})}
</Select>
Og så er dette funksjonen som oppretter disse menyvalgene, samt betingelsene for å sette standardverdien:
const actions = useMemo(() => {
let allActions: Array<{ text: string, value: string }> = [
{ text: 'Notify SME for Review', value: 'sme' },
{ text: 'Return for Review', value: 'review' },
{ text: 'Notify Sales for Review', value: 'notify' },
{ text: 'Release to Agent', value: 'release' }
];
if (groups.includes('SME')) {
allActions = [{ text: 'Notify Sales for Review', value: 'notify' }, { text: 'Return for Review', value: 'review' },]
} else if (groups.includes('IT')) {
allActions = [{ text: 'Notify SME for Review', value: 'sme' },]
} else if (groups.includes('Sales')) {
allActions = [{ text: 'Release to Agent', value: 'release' }]
}
// This will select the second item in the select element when it's IT or Sales
if (groups.includes('IT') || groups.includes('Sales')) {
const dropdown = document.getElementById('dropdown')!.selectedIndex = "1";
}
return allActions;
}, [groups]);
Svar #1
Problemet du står overfor løses ved å forstå Reacts enveis dataflyt. Din sannhetskilde bør alltid komme ovenfra.
Med mer konkrete ord, ville du ikke lese eller skrive direkte til ditt #select-element, men i stedet ville du ha en tilstandsverdi for det, som ville være din kilde til sannhet:
const MyComponent = ({ groups }) => {
const [selectedIndex, setSelectedIndex] = useState(0) // or the default value
/**
* In here, you'll let react know that you want some code to run, when
* this property changes in the outside world
*/
useEffect(() => {
if (groups.includes('IT') || groups.includes('Sales')) {
setSelectedIndex(1)
}
}, [groups]);
// ...
return (
<Select
value={selectedIndex}
....other props...
>
... children
</Select>
)
}
Egentlig bruker du ikke document.getElementId.
Svar #2
Du må fortelle TypeScript at du lager en nettleserapp via tsconfig.json. Du kan legge til en lib-egenskap med verdien dom. Et eksempel:
{
"compilerOptions": {
"lib": ["es5", "es6", "dom"], // <-- here
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es6",
"moduleResolution": "node",
"jsx": "react"
},
"include": ["./src/**/*"]
}
Dette vil tillate TypeScript å gjenkjenne document som et gyldig grensesnitt.
Når det er ute av veien, er en idiomatisk tilnærming for å velge DOM-noder i React-funksjonskomponenter med useRef.
import React, { useRef, useEffect } from 'react'
const SomeComponent = ({ innerRef }) => (
<div ref={innerRef}>some div</div>
)
const ParentComponent = () => {
const ref = useRef()
useEffect(() => {
if(ref.current) {
console.log(ref.current.selectedIndex)
}
}, [ref.current])
return <SomeComponent innerRef={ref} />
}
En ref trenger ikke å bli sendt fra en forelder. Den kan brukes i samme dokument. Jeg la det bare til i tilfelle brukstilfellet ditt krevde det.
