Javascript React组件未使用贴图功能进行渲染
调用loadAll()时,不会呈现我的LinkItem组件。仅在调用handleClick()或handleChange()后渲染Javascript React组件未使用贴图功能进行渲染,javascript,reactjs,Javascript,Reactjs,调用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
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 });
}
检索完文档后,您需要在回调中调用
setState
:
代码
或者干脆做:
loadAll() {
db.find({ type: "link" }, function(err, docs) {
this.setState({ data: docs.map(doc => doc.name)});
});
}
必须这样做的原因是因为db.find
是一个异步函数因此,它将返回中间值,因此加载数据
将等于[]
您还可以将loadAll
声明为async,并使用wait:
loadAll() {
const docs = await db.find({ type: "link" });
this.setState({ data: docs.map(doc => doc.name) });
}
顺便说一句,有一些技巧可以缩短代码:
状态
,就可以摆脱构造函数import React,{Component}来自“React”;
var数据存储=要求(“nedb”);
var db=新数据存储({filename:uu dirname+“/userdata”});
db.loadDatabase(函数(错误){
});
功能链接项(道具){
控制台日志(“呈现”);
返回(
);
}
导出默认类列表扩展组件{
状态={
链接:“,
数据:[],
}
loadAll=async()=>{
const docs=await db.find({type:“link”});
this.setState({data:docs.map(doc=>doc.name)});
}
//向数据集添加新项
handleClick=()=>{
const{data,link}=this.state;
这是我的国家({
数据:[……数据,链接]
});
const doc={name:this.state.link,键入:“link”};
db.insert(文档,(错误,文档)=>{
控制台日志(“插入”);
console.log(文档);
});
}
//处理表单输入更改
handleChange=(事件)=>{
this.setState({link:event.target.value});
}
render(){
const{data}=this.state;
返回(
加载数据
添加
{console.log(数据)}
{/*呈现每个数据*/}
{data.map((项目,索引)=>(
))}
);
}
}
请注意,render
不需要声明为箭头函数,因为它由React自动绑定
让我知道这是否有效,否则,请告诉我出了什么问题。检索完文档后,您需要在回调中调用
setState
:
代码
或者干脆做:
loadAll() {
db.find({ type: "link" }, function(err, docs) {
this.setState({ data: docs.map(doc => doc.name)});
});
}
必须这样做的原因是因为db.find
是一个异步函数因此,它将返回中间值,因此加载数据
将等于[]
您还可以将loadAll
声明为async,并使用wait:
loadAll() {
const docs = await db.find({ type: "link" });
this.setState({ data: docs.map(doc => doc.name) });
}
顺便说一句,有一些技巧可以缩短代码:
状态
,就可以摆脱构造函数import React,{Component}来自“React”;
var数据存储=要求(“nedb”);
var db=新数据存储({filename:uu dirname+“/userdata”});
db.loadDatabase(函数(错误){
});
功能链接项(道具){
控制台日志(“呈现”);
返回(
);
}
导出默认类列表扩展组件{
状态={
链接:“,
数据:[],
}
loadAll=async()=>{
const docs=await db.find({type:“link”});
this.setState({data:docs.map(doc=>doc.name)});
}
//向数据集添加新项
handleClick=()=>{
const{data,link}=this.state;
这是我的国家({
数据:[……数据,链接]
});
const doc={name:this.state.link,键入:“link”};
db.insert(文档,(错误,文档)=>{
控制台日志(“插入”);
console.log(文档);
});
}
//处理表单输入更改
handleChange=(事件)=>{
this.setState({link:event.target.value});
}
render(){
const{data}=this.state;
返回(
加载数据
添加
{console.log(数据)}
{/*呈现每个数据*/}
{data.map((项目,索引)=>(
))}
);
}
}
请注意,render
不需要声明为箭头函数,因为它由React自动绑定
让我知道这是否有效,否则,告诉我出了什么问题。您的
db.find
函数是异步的,您的程序将继续运行,而不是等待它完成:
loadAll() {
let loadData = [];
db.find({ type: "link" }, function(err, docs) {
docs.map(doc => loadData.push(doc.name));
});
this.setState({ data: loadData });
}
您有两个解决方案来修复它
将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;
您的
db.find
函数是异步的,您的程序将继续运行,而不是等待它完成:
loadAll() {
let loadData = [];
db.find({ type: "link" }, function(err, docs) {
docs.map(doc => loadData.push(doc.name));
});
this.setState({ data: loadData });
}
您有两个解决方案来修复它
将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函数还将返回一个包含值的新数组。下面的语法是s