我正在尝试使用gatsby(反应)和Fuse.js创建离线模糊搜索,并且遇到了使用setState存储“搜索”字词的问题。
我收到以下错误: 重新渲染过多。 React限制了渲染次数以防止无限循环。
我不确定如何保存新状态(下面的代码)
const [posts, setPosts] = useState(null)
useEffect(() => {
fetch("/index.json")
.then(response => response.json())
.then(function(data) {
setPosts(data.data.allContentfulPost.edges)
})
}, [])
if (posts) {
var list = posts //returns 326 items
var options = {
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: ["node.title", "node.meta"],
}
var fuse = new Fuse(list, options)
var results = fuse.search("marketing") //returns 11 items
setPosts(results) //causes infinite loop
}
答案 0 :(得分:0)
除了极少数的用例,您不应该在组件render方法中直接调用setState
,如果这样做,则需要谨慎选择正确的条件。
通常情况是这样,如果您的状态取决于提供给组件的道具。基于类的组件生命周期方法称为getDerivedStateFromProps
。您不需要这里。
您似乎正在尝试缩小API端点的结果。可以在调用setPosts
之前在fetch回调中完成转换:
useEffect(() => {
fetch("/index.json")
.then(response => response.json())
.then(function(data) {
const allPosts = data.data.allContentfulPost.edges;
const options = {
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: ["node.title", "node.meta"],
}
const fuse = new Fuse(allPosts, options)
const found = fuse.search("marketing")
setPosts(found);
})
}, [])
答案 1 :(得分:0)
解决此问题的一种方法是对已过滤的帖子使用另一种状态。并保留原始帖子以备将来使用:
const [posts, setPosts] = useState([]);
const [filteredPosts, setFilteredPosts] = useState([]);
useEffect(() => {
fetch("/index.json")
.then(response => response.json())
.then(function(data) {
setPosts(data.data.allContentfulPost.edges)
})
}, []);
useEffect(() => {
var options = {
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: ["node.title", "node.meta"],
}
var fuse = new Fuse(posts, options)
var results = fuse.search("marketing") //returns 11 items
setFilteredPosts(results)
}, [posts])