我正在尝试在我的 React 应用程序中创建一个全局警报,该警报显示在屏幕顶部并且每个组件都可以使用。我有在 App 中使用的组件 GlobalAlert。
当我尝试从路由中的任何组件传递 GlobalAlert 的 setAlert 函数时,就会出现问题。我尝试像这样使用 React Refs:
const GlobalAlert = React.forwardRef((props, ref) => {
const [variant, setVariant] = useState(null)
const [message, setMessage] = useState(null)
const setAlert = (vrnt, msg) => {
setVariant(vrnt)
setMessage(msg)
setTimeout(() => {
setMessage(null)
}, 5000)
}
useImperativeHandle(ref, () => {
return {
setAlert,
}
})
if (message) {
return (
<div>
<Alert variant={variant}>{message}</Alert>
</div>
)
}
return (
<div>
<br />
<br />
<br />
</div>
)
})
const App = () => {
const alertRef = React.createRef()
const setAlert = (variant, message) => {
alertRef.current.setAlert(variant, message)
}
return (
<div className="container">
<Router>
<Menu />
<GlobalAlert ref={alertRef} />
<Routes setAlert={setAlert} />
</Router>
</div>
)
}
当我在NewIngredient中的后端操作完成后尝试使用 setAlert 时:
const NewIngredient = ({ setAlert }) => {
...(excluded logic here)...
const submit = async e => {
e.preventDefault()
try {
await addIngredient({
variables: {
name: name.value,
price: Number(price.value),
...(kcal.value && { kcal: Number(kcal.value) }),
},
})
} catch (error) {
console.log('Error adding ingredient in NewIngredient.js', error.message)
}
setAlert('success', `New Ingredient ${name.value} added!`)
resetName()
resetPrice()
resetKcal()
}
return (
<div>
<Form onSubmit={submit}>
<Form.Group>
<Form.Label>Name</Form.Label>
<Form.Control {...name} />
<Form.Label>Price</Form.Label>
<Form.Control {...price} />
<Form.Label>Kcal</Form.Label>
<Form.Control {...kcal} />
<Button type="submit">Add ingredient</Button>
</Form.Group>
</Form>
</div>
)
}
Unhandled Rejection (TypeError): Cannot read property 'setAlert' of null
setAlert
src/App.js:27
24 | const alertRef = React.createRef()
25 |
26 | const setAlert = (variant, message) => {
> 27 | alertRef.current.setAlert(variant, message)
28 | ^ }
29 |
submit
src/Ingredient/Forms/NewIngredient.js:49
46 | console.log('Error adding ingredient in NewIngredient.js', error.message)
47 | }
48 |
> 49 | setAlert('success', `New Ingredient ${name.value} added!`)
50 | ^
51 | resetName()
52 | resetPrice()
此外,如果我让它工作,它需要无意识的道具钻取组件结构。
如果可能的话,我宁愿不使用 Redux,因为我使用 Apollo 客户端来处理我所有应用程序的状态。我尝试使用 React Context API,但我发现无法为 NewIngredient 的提交函数传递 setAlert 函数。
有没有明确而简单的解决方案?