I am making an simple google Keep-like note react app. I use XMasonry
for layout. and I want to add animation using react-spring
to make it fade in and out on delete and create item list. But I keep getting error why trying to make Xmasonry work with react-spring. what am I missing here ? should I use useString
or Transition
.
(https://prnt.sc/t9y1ox)
const InitialNotes = [
{
key: 1,
title: "Delegation",
content:
"Q. How many programmers does it take to change a light bulb? A. None β Itβs a hardware problem",
},
{
key: 2,
title: "Loops",
content:
"How to keep a programmer in the shower forever. Show him the shampoo bottle instructions: Lather. Rinse. Repeat.",
},
{
key: 3,
title: "Arrays",
content:
"Q. Why did the programmer quit his job? A. Because he didn't get arrays.",
},
{
key: 4,
title: "Hardware vs. Software",
content:
"What's the difference between hardware and software? You can hit your hardware with a hammer, but you can only curse at your software.",
},
];
function App() {
const [notes, setNotes] = useState(InitialNotes);
function addNoteHandler(note) {
setNotes((prevNotes) => {
return [...prevNotes, note];
});
}
function onEditNote(idx, toUpdateNote) {
const newNotes = [...notes];
newNotes[idx] = toUpdateNote;
setNotes(newNotes);
}
function deleteNote(id) {
setNotes((notes) =>
notes.filter((note, idx) => {
return note.key !== id;
})
);
}
return (
<div className="App">
<AddNote addNoteHandler={addNoteHandler} />
<div className="container">
<XMasonry>
<Transition
items={notes}
keys={(note) => note.key}
from={{ opacity: 0 }}
enter={{ opacity: 1 }}
leave={{ opacity: 0 }}
>
{(note) => (styles) => (
<animated.div styles={styles}>
<XBlock>
<Note
id={note.key}
key={note.key}
title={note.title}
content={note.content}
deleteNote={deleteNote}
onEditNote={onEditNote}
/>
</XBlock>
</animated.div>
)}
</Transition>
</XMasonry>
</div>
</div>
);
}
function Note(props) {
const initialNote = {
id: "",
title: "",
content: "",
};
const [IsEdit, setIsEdit] = useState(false);
// const [Zindex, setZindex] = useState({ zIndex: "1" });
// const [isDelete, setIsDelete] = useState(false);
const [note, setNote] = useState(initialNote);
function AutoResize() {
this.style.height = "auto";
this.style.height = this.scrollHeight + "px";
}
function setAutoResize() {
const textarea1 = document.querySelector("#auto-resizing1");
console.log(textarea1);
textarea1.addEventListener("input", AutoResize, false);
}
useEffect(() => {
const updateNote = {
id: props.id,
title: props.title,
content: props.content,
};
setNote(updateNote);
if (IsEdit) setAutoResize();
}, []);
function onDelete(e) {
// setIsDelete(true);
console.log("Delete iTem");
props.deleteNote(props.id);
e.preventDefault();
}
function onChange(e) {
const { name, value } = e.target;
setNote((prevNote) => {
return { ...prevNote, [name]: value };
});
}
const onEdit = () => {
return (
<div className="note">
<input
type="text"
name="title"
value={note.title}
onChange={onChange}
/>
<textarea
id="auto-resizing1"
type="text"
name="content"
value={note.content}
onChange={onChange}
/>
<button
onClick={() => {
props.onEditNote(props.id, note);
setIsEdit(false);
}}
>
<SendIcon />
</button>
<button onClick={() => setIsEdit(false)}>
<CloseIcon />
</button>
</div>
);
};
const onShow = () => {
return (
<div className="note">
<h1>{props.title}</h1>
<p>{props.content}</p>
<button onClick={onDelete}>
<DeleteIcon />
</button>
<button onClick={() => setIsEdit(true)}>
<EditIcon />
</button>
</div>
);
};
return IsEdit ? onEdit() : onShow();
}
Here is my code: https://codesandbox.io/s/google-keep-note-ny71j?file=/src/App.js