Javascript React组件未使用贴图功能进行渲染

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

调用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 });
  }

检索完文档后,您需要在回调中调用
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