Я выделил мою проблему здесь, чтобы вы могли легко воспроизвести это. Шаги для воспроизведения:
Шаг 1: создать приложение реагирования и добавить material-ui
в проект:
prompt> create-react-app mui-test
prompt> cd mui-test
prompt> yarn add @material-ui/core @material-ui/icons
Шаг 2: измените следующие файлы:
index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<App />,
document.getElementById('root')
)
App.tsx
import React, { useState } from 'react'
import { Button, Snackbar } from '@material-ui/core'
interface MessageComponentProps { messages: string[] }
export const MessageComponent: React.FC<MessageComponentProps> = ({ messages }) => {
console.log("Render MessageComponent... messages: ", messages)
console.log("messages.length > 0: ", messages.length > 0);
// This shows the Snackbar once but when I reclick the submit button,
// it doesn't do it again.
const [showMessage, setShowMessage] = useState(true)
const onClose = () => {
console.log("calling onClose()...")
setShowMessage(false)
}
if (messages.length === 0) return <></>
return <>
<Snackbar
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
key={`top,center`}
open={showMessage}
// eventurally I want to display all messages but this will work for now.
message={messages[0]}
onClose={onClose}
/>
Proof that Snackbar should be rendered here: {messages[0]}
</>
}
export const PageComponent: React.FC = () => {
console.log("Render PageComponent...")
const [errors, setErrors] = useState<string[]>([])
const onSubmit = (e: any) => {
e.preventDefault()
// simulates a collection of error messages sent back from the server to
// show to the user.
setErrors(['Foo ' + Math.random(), 'Bar'])
}
return <>
<MessageComponent messages={errors} />
<form onSubmit={onSubmit} >
<Button type="submit" color="primary" variant="contained">Submit</Button>
</form>
<p>
What I'm trying to accomplish here is that whenever this button is clicked,
The snackbar should show and then be cleared when the user clicks away from
the message. It only does this the first time but doesn't any of the
consecutive clicks.
</p>
</>
}
function App() {
console.log("Render App...")
return <PageComponent />
}
export default App
Проблема: Я могу получить всплывающее сообщение SnackBar
, но когда я пытаюсь закрыть его, оно никогда не появляется, несмотря на вызываемый метод onClose
. Когда я пытаюсь это исправить, он никогда не открывается (см. Некоторые комментарии в коде для того, что я пытаюсь сделать здесь)
В какой-то момент я мог заставить SnackBar
закрыться , Однако нажатие кнопки Submit
должно привести к тому, что сообщение SnackBar
снова появится, но никогда после первого раза. Единственный способ вернуть его - это перезагрузить страницу и нажать кнопку еще раз.
Я все еще новичок в React, поэтому я борюсь с этим, но у меня есть подозрение, что этот рецепт требует useEffect
?