gpt4 book ai didi

javascript - React 组件未使用 map 函数渲染

转载 作者:行者123 更新时间:2023-11-28 17:11:49 25 4
gpt4 key购买 nike

调用 loadAll() 时,我的 LinkItem 组件不会呈现。它仅在调用handleClick() 或handleChange() 后才会呈现。

import React, { Component } from "react";
var Datastore = require("nedb");
var db = new Datastore({ filename: __dirname + "/userdata" });
db.loadDatabase(function(err) {

});

function LinkItem(props) {
console.log("Rendered");
return (
<div>
<a href={props.name}>{props.name}</a>
</div>
);
}

export default class List extends Component {
constructor(props) {
super(props);
this.state = {
link: "",
data: [],
};
this.handleClick = this.handleClick.bind(this);
this.handleChange = this.handleChange.bind(this);
this.loadAll = this.loadAll.bind(this);
}

loadAll() {
let loadData = [];
db.find({ type: "link" }, function(err, docs) {
docs.map(doc => loadData.push(doc.name));
});
this.setState({ data: loadData });
}

// add new item to data set
handleClick() {
this.setState({
data: [...this.state.data, this.state.link]
});
const doc = { name: this.state.link, type: "link" };
db.insert(doc, (err, docs) => {
console.log("Inserted");
console.log(docs);
});
}

// handles form input changes
handleChange(event) {
this.setState({ link: event.target.value });
}

在渲染函数中,我使用 map 来渲染每个 LinkItem 组件。但是,当我在 LinkItem 组件中检查 console.log 时,它们根本没有被创建。它们仅在handleClick 和handleChange 被调用时出现。

  render() {
const data = this.state.data;

return (
<div>
<button onClick={this.loadAll}>Load data</button>
<input
type="text"
value={this.state.link}
onChange={this.handleChange}
/>
<button onClick={this.handleClick}>Add</button>
{console.log(data)}
{/* render each data */}
{data.map((item, index) => (
<LinkItem name={item} key={index} />
))}
</div>
);
}

}

基本上我想要发生的是当调用 loadData 时,所有数据都在 LinkItem 组件中呈现。

注意:这不是重复的。我检查了 stackoverflow 中的其他问题,其中它们在 map 函数中没有返回。我的情况并非如此。仅当其他状态值发生变化时,它才会最终呈现。

编辑:我可以通过将 setState 放入 db find 并将回调更改为箭头函数来修复它。对于那些使用 nedb 和 React 的人来说,这可能会有所帮助。

  loadAll() {
db.find({ type: "link" }, (err, docs) => { // changed to arrow function
this.setState({ data: docs.map(doc => doc.name)});
});
}

最佳答案

您的 db.find 函数是异步的,您的程序将继续运行而不等待它完成:

  loadAll() {
let loadData = [];
db.find({ type: "link" }, function(err, docs) {
docs.map(doc => loadData.push(doc.name));
});
this.setState({ data: loadData });
}

您有 2 个解决方案来修复它。

setState 放入回调中:

  loadAll() {
let loadData = [];
db.find({ type: "link" }, function(err, docs) {
docs.map(doc => loadData.push(doc.name));
this.setState({ data: loadData });
});
}

或等待您的来电:

  loadAll = async() => {
let loadData = [];
const docs = await db.find({ type: "link" });
docs.map(doc => loadData.push(doc.name));
this.setState({ data: loadData });
}

此外,map 函数将返回一个包含您的值的新数组。以下语法更短并且执行相同的操作:

loadAll = async () => {
this.setState({
data: (await db.find({ type: "link" })).map(doc => doc.name)
});
}

我还注意到您在 setState 中使用了状态值。 React 建议在回调中使用之前的状态来执行此操作并避免意外行为:

handleClick() {
this.setState(prevState => {
data: [...prevState.data, prevState.link]
});

您可以使用的另一件事是解构,这段代码:

const data = this.state.data;

可能成为:

const { data } = this.state;

关于javascript - React 组件未使用 map 函数渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54187602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com