如何在 FP 中引用当前状态?
How to refer to the current state in FP?
我已经问过这个问题,但我的解释很糟糕,所以我决定用更好的解释和实际代码再次提问(我会要求版主删除其中一个帖子)。那么让我们考虑一下这个问题。
以下代码段表示从数组渲染注释。然而,在 adding note 部分,我改变了一个状态。所以问题是:如何在不改变的情况下在 notes
数组中添加新注释?换句话说,我想删除 replaceNotes
并保留相同的功能。我知道可以在没有数组的情况下添加注释,但由于将来的参考,我确实需要用注释更新数组。问题是,在我原来的应用程序中,我有带注释的列表,当我在列表之间切换时,我应该得到依赖于我打开的列表的渲染注释。这就是为什么我应该保留对 notes
数组的引用。
同时我在想,如果我只是将 notes
存储在 localStorage
中,然后从该数据中做笔记,是否可以?这是函数式编程的好习惯吗?
const button = document.getElementById('button');
const notesContainer = document.querySelector('.notes');
const pipe = (f, g) => (...args) => f(g(...args));
let notes = [];
const createNote = (...fns) => fns.reduceRight(pipe);
const handleEvent = () =>
createNote(gatherContent, renderContent, replaceNotes)(notes);
function gatherContent(notes) {
const name = prompt('How do you want to name a note?');
return [...notes, { name }];
}
function renderContent(notes) {
function render(note) {
const noteEl = document.createElement('div');
noteEl.innerHTML = `<p>${note.name}</p>`;
notesContainer.append(noteEl);
}
notesContainer.innerHTML = '';
notes.map(render);
return notes;
}
const replaceNotes = newNotes => (notes = newNotes);
button.addEventListener('click', handleEvent);
<button id="button">Click me!</button>
<section class="notes"></section>
下面是如何创建一个简单的任务列表应用程序,除了 DOM。
const button = document.getElementById("button");
const section = document.getElementById("notes");
const template = document.getElementById("template");
template.parentNode.removeChild(template);
const render = notes => {
button.onclick = event => {
const name = prompt("How do you want to name a note?");
render([...notes, { name }]);
};
while (section.lastChild) {
section.removeChild(section.lastChild);
}
for (const note of notes) {
const node = template.cloneNode(true);
node.firstChild.firstChild.nodeValue = note.name;
section.appendChild(node);
}
};
render([]);
<button id="button">Click me!</button>
<section id="notes"></section>
<div id="template"><p>name</p></div>
详细解释请看我之前的回答。
您也可以将此模式与 localStorage
一起使用。
const button = document.getElementById("button");
const section = document.getElementById("notes");
const template = document.getElementById("template");
template.parentNode.removeChild(template);
const render = notes => {
localStorage.setItem("notes", notes); // set notes
button.onclick = event => {
const name = prompt("How do you want to name a note?");
render([...notes, { name }]);
};
while (section.lastChild) {
section.removeChild(section.lastChild);
}
for (const note of notes) {
const node = template.cloneNode(true);
node.firstChild.firstChild.nodeValue = note.name;
section.appendChild(node);
}
};
render(localStorage.getItem("notes") || []); // get notes
请注意,localStorage
应该只用于保存您想要跨会话使用的状态。不建议使用 localStorage
作为您的应用程序商店。这将导致糟糕的性能和糟糕的代码结构。
我已经问过这个问题,但我的解释很糟糕,所以我决定用更好的解释和实际代码再次提问(我会要求版主删除其中一个帖子)。那么让我们考虑一下这个问题。
以下代码段表示从数组渲染注释。然而,在 adding note 部分,我改变了一个状态。所以问题是:如何在不改变的情况下在 notes
数组中添加新注释?换句话说,我想删除 replaceNotes
并保留相同的功能。我知道可以在没有数组的情况下添加注释,但由于将来的参考,我确实需要用注释更新数组。问题是,在我原来的应用程序中,我有带注释的列表,当我在列表之间切换时,我应该得到依赖于我打开的列表的渲染注释。这就是为什么我应该保留对 notes
数组的引用。
同时我在想,如果我只是将 notes
存储在 localStorage
中,然后从该数据中做笔记,是否可以?这是函数式编程的好习惯吗?
const button = document.getElementById('button');
const notesContainer = document.querySelector('.notes');
const pipe = (f, g) => (...args) => f(g(...args));
let notes = [];
const createNote = (...fns) => fns.reduceRight(pipe);
const handleEvent = () =>
createNote(gatherContent, renderContent, replaceNotes)(notes);
function gatherContent(notes) {
const name = prompt('How do you want to name a note?');
return [...notes, { name }];
}
function renderContent(notes) {
function render(note) {
const noteEl = document.createElement('div');
noteEl.innerHTML = `<p>${note.name}</p>`;
notesContainer.append(noteEl);
}
notesContainer.innerHTML = '';
notes.map(render);
return notes;
}
const replaceNotes = newNotes => (notes = newNotes);
button.addEventListener('click', handleEvent);
<button id="button">Click me!</button>
<section class="notes"></section>
下面是如何创建一个简单的任务列表应用程序,除了 DOM。
const button = document.getElementById("button");
const section = document.getElementById("notes");
const template = document.getElementById("template");
template.parentNode.removeChild(template);
const render = notes => {
button.onclick = event => {
const name = prompt("How do you want to name a note?");
render([...notes, { name }]);
};
while (section.lastChild) {
section.removeChild(section.lastChild);
}
for (const note of notes) {
const node = template.cloneNode(true);
node.firstChild.firstChild.nodeValue = note.name;
section.appendChild(node);
}
};
render([]);
<button id="button">Click me!</button>
<section id="notes"></section>
<div id="template"><p>name</p></div>
详细解释请看我之前的回答。
您也可以将此模式与 localStorage
一起使用。
const button = document.getElementById("button");
const section = document.getElementById("notes");
const template = document.getElementById("template");
template.parentNode.removeChild(template);
const render = notes => {
localStorage.setItem("notes", notes); // set notes
button.onclick = event => {
const name = prompt("How do you want to name a note?");
render([...notes, { name }]);
};
while (section.lastChild) {
section.removeChild(section.lastChild);
}
for (const note of notes) {
const node = template.cloneNode(true);
node.firstChild.firstChild.nodeValue = note.name;
section.appendChild(node);
}
};
render(localStorage.getItem("notes") || []); // get notes
请注意,localStorage
应该只用于保存您想要跨会话使用的状态。不建议使用 localStorage
作为您的应用程序商店。这将导致糟糕的性能和糟糕的代码结构。