Closed LorhanSohaky closed 3 years ago
Any update in this issue??? even i am facing same problem while updating quantity
You need to wrap your content in a React component to get state working. Take a look at this closed issue:
https://github.com/sweetalert2/sweetalert2-react-content/issues/52
For example, instead of this:
ReactSwal.fire({
html: (
<input type="text" value={value} />
)
})
You would have something like this:
const Component = (props) => {
const [value, setValue] = useState('');
return (
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}
/>
);
}
ReactSwal.fire({
html: (
<Component />
)
})
thank you
@ant-fx , but how to expose the state to outside the component?
For example:
const Component = (props) => {
const [value, setValue] = useState('');
return (
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}
/>
);
}
// ...
const openPopup = async () => {
const { isConfirmed } = await ReactSwal.fire({
html: (
<Component />
)
if (isConfirmed) {
await submitDate(popupData)
}
})
}
how to expose the state to outside the component?
@LorhanSohaky Maybe there will be some better suggestion, but I have one:
const Component = (props) => {
const [value, setValue] = useState('');
+ useEffect(() => { props.onValue(value) }, [value]);
return (
<input
type="text"
value={value}
onChange={(e) => {
setValue(e.target.value);
}
/>
);
}
// ...
const openPopup = async () => {
+ let popupData;
const { isConfirmed } = await ReactSwal.fire({
html: (
- <Component />
+ <Component onValue={value => { popupData = value }} />
)
if (isConfirmed) {
await submitDate(popupData)
}
})
}
@LorhanSohaky Do you have a comment about my suggested solution? Or just the 👀 emoji? Does it not work?
Closing this because
@LorhanSohaky You're welcome
This seems complicated, do we have easy solutions? if the state isn't a simple value. For example:
export default function SettingsForm({ readerOptions, setReaderOptions }) {
I need to change state by call setReaderOptions
but HTML was rendered Swal don't update it.
@LorhanSohaky Do you have a comment about my suggested solution? Or just the eyes emoji? Does it not work?
Its work for me, tks
I am late to the party but I hope this can help someone. You can use React Portal to render items inside the modal content.
import Swal from "sweetalert2";
import { createPortal } from "react-dom";
import withReactContent from "sweetalert2-react-content";
import { useEffect, useState, useCallback } from "react";
function App() {
const [shown, setShown] = useState(false);
const [value, setValue] = useState("");
const handleClick = useCallback(function handleClick() {
setShown(true);
}, []);
const handleClose = useCallback(function handleClose() {
setShown(false);
}, []);
const handleChange = useCallback(function handleChange(e) {
setValue(e.target.value);
}, []);
return (
<div>
<h1>{value}</h1>
<button onClick={handleClick}>Alert</button>
<SweetAlert2 show={shown} onClose={handleClose}>
<input onChange={handleChange} value={value} />
</SweetAlert2>
</div>
);
}
const MySwal = withReactContent(Swal);
const SweetAlert2 = ({ children, show, onClose }) => {
const [container, setContainer] = useState(null);
useEffect(() => {
if (show) {
MySwal.fire({
html: <div ref={(el) => setContainer(el)} />
}).then(() => {
onClose && onClose();
});
}
}, [show, onClose]);
if (container) {
return createPortal(children, container);
}
return null;
};
@ramilamparo Did not know this function, very cool!
I am late to the party but I hope this can help someone. You can use React Portal to render items inside the modal content.
import Swal from "sweetalert2"; import { createPortal } from "react-dom"; import withReactContent from "sweetalert2-react-content"; import { useEffect, useState, useCallback } from "react"; function App() { const [shown, setShown] = useState(false); const [value, setValue] = useState(""); const handleClick = useCallback(function handleClick() { setShown(true); }, []); const handleClose = useCallback(function handleClose() { setShown(false); }, []); const handleChange = useCallback(function handleChange(e) { setValue(e.target.value); }, []); return ( <div> <h1>{value}</h1> <button onClick={handleClick}>Alert</button> <SweetAlert2 show={shown} onClose={handleClose}> <input onChange={handleChange} value={value} /> </SweetAlert2> </div> ); } const MySwal = withReactContent(Swal); const SweetAlert2 = ({ children, show, onClose }) => { const [container, setContainer] = useState(null); useEffect(() => { if (show) { MySwal.fire({ html: <div ref={(el) => setContainer(el)} /> }).then(() => { onClose && onClose(); }); } }, [show, onClose]); if (container) { return createPortal(children, container); } return null; };
@ramilamparo Nice! but using this showLoaderOnConfirm stopped working for me... (even though preConfirm does work!) does this reproduce for you also? any advice???
https://codesandbox.io/s/bug-sweetalert-react-y763q