繁体   English   中英

React.js不会在状态更新时重新呈现应用程序

[英]React.js not re-rendering app on state update

我正在研究基于React.js的大纲器(类似于工作流)。 我陷入了困境。 当我在任何一项上按Enter键时,我想在其下方插入另一项。

因此,我已经使用setState函数将一个项目插入到当前项目的正下方,如下面的代码片段所示:

 this.setState({
      items: this.state.items.splice(this.state.items.map((item) => item._id).indexOf(itemID) + 1, 0, {_id: (new Date().getTime()), content: 'Some Note'})
 })

但是,该应用程序重新呈现为空白,没有出现任何错误。

到目前为止,我的完整资料来源:

import './App.css';

import React, { Component } from 'react';
import ContentEditable from 'react-contenteditable';

const items = [
  {
    _id: 0,
    content: 'Item 1 something',
    note: 'Some note for item 1'
  },
  {
    _id: 5,
    content: 'Item 1.1 something',
    note: 'Some note for item 1.1'
  },
  {
    _id: 1,
    content: 'Item 2 something',
    note: 'Some note for item 2',
    subItems: [
      {
        _id: 2,
        content: 'Sub Item 1 something',
        subItems: [{
          _id: 3,
          content: 'Sub Sub Item 4'
        }]
      }
    ]
  }
];

class App extends Component {
  render() {
    return (
      <div className="App">
        <Page items={items} />
      </div>
    );
  }
}

class Page extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: this.props.items
    };

    this.insertItem = this.insertItem.bind(this);
  }

  render() {
    return (
      <div className="page">
        {
          this.state.items.map(item =>
            <Item _id={item._id} content={item.content} note={item.note} subItems={item.subItems} insertItem={this.insertItem} />
          )
        }
      </div>
    );
  }

  insertItem(itemID) {
    console.log(this.state.items);

    this.setState({
      items: this.state.items.splice(this.state.items.map((item) => item._id).indexOf(itemID) + 1, 0, {_id: (new Date().getTime()), content: 'Some Note'})
    })

    console.log(this.state.items);
  }
}

class Item extends Component {
  constructor(props) {
    super(props);

    this.state = {
      content: this.props.content,
      note: this.props.note
    };

    this.saveItem = this.saveItem.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }

  render() {
    return (
      <div key={this.props._id} className="item">
        <ContentEditable html={this.state.content} disabled={false} onChange={this.saveItem} onKeyPress={(event) => this.handleKeyPress(this.props._id, event)} />

        <div className="note">{this.state.note}</div>
        {
          this.props.subItems &&
          this.props.subItems.map(item =>
            <Item _id={item._id} content={item.content} note={item.note} subItems={item.subItems} insertItem={this.insertItem} />
          )
        }
      </div>
    );
  }

  saveItem(event) {
    this.setState({
      content: event.target.value
    });
  }

  handleKeyPress(itemID, event) {
    if (event.key === 'Enter') {
      event.preventDefault();
      console.log(itemID);
      console.log(event.key);
      this.props.insertItem(itemID);
    }
  }
}

export default App;

github仓库: https : //github.com/Hirvesh/mneme

任何人都可以帮助我了解为什么更新项目后无法再次渲染吗?

编辑:

我已经更新了代码以添加键,如下所示,尽管状态正在更新,但仍呈现为空白:

import './App.css';

import React, { Component } from 'react';
import ContentEditable from 'react-contenteditable';

const items = [
  {
    _id: 0,
    content: 'Item 1 something',
    note: 'Some note for item 1'
  },
  {
    _id: 5,
    content: 'Item 1.1 something',
    note: 'Some note for item 1.1'
  },
  {
    _id: 1,
    content: 'Item 2 something',
    note: 'Some note for item 2',
    subItems: [
      {
        _id: 2,
        content: 'Sub Item 1 something',
        subItems: [{
          _id: 3,
          content: 'Sub Sub Item 4'
        }]
      }
    ]
  }
];

class App extends Component {
  render() {
    return (
      <div className="App">
        <Page items={items} />
      </div>
    );
  }
}

class Page extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: this.props.items
    };

    this.insertItem = this.insertItem.bind(this);
  }

  render() {
    return (
      <div className="page">
        {
          this.state.items.map(item =>
            <Item _id={item._id} key={item._id} content={item.content} note={item.note} subItems={item.subItems} insertItem={this.insertItem} />
          )
        }
      </div>
    );
  }

  insertItem(itemID) {
    console.log(this.state.items);

    this.setState({
      items: this.state.items.splice(this.state.items.map((item) => item._id).indexOf(itemID) + 1, 0, {_id: (new Date().getTime()), content: 'Some Note'})
    })

    console.log(this.state.items);
  }
}

class Item extends Component {
  constructor(props) {
    super(props);

    this.state = {
      content: this.props.content,
      note: this.props.note
    };

    this.saveItem = this.saveItem.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }

  render() {
    return (
      <div className="item">
        <ContentEditable html={this.state.content} disabled={false} onChange={this.saveItem} onKeyPress={(event) => this.handleKeyPress(this.props._id, event)} />

        <div className="note">{this.state.note}</div>
        {
          this.props.subItems &&
          this.props.subItems.map(item =>
            <Item _id={item._id} key={item._id} content={item.content} note={item.note} subItems={item.subItems} insertItem={this.insertItem} />
          )
        }
      </div>
    );
  }

  saveItem(event) {
    this.setState({
      content: event.target.value
    });
  }

  handleKeyPress(itemID, event) {
    if (event.key === 'Enter') {
      event.preventDefault();
      console.log(itemID);
      console.log(event.key);
      this.props.insertItem(itemID);
    }
  }
}

export default App;

编辑2:

根据以下建议,添加了key = {i._id}仍然无法正常工作,如果有人想看一下,将最新代码推送到github。

  this.state.items.map((item, i) =>
    <Item _id={item._id} key={i._id} content={item.content} note={item.note} subItems={item.subItems} insertItem={this.insertItem} />
  )

您错过了在Item上放置密钥的原因,因为该React无法识别您的状态是否改变。

<div className="page">
{
  this.state.items.map((item, i) =>
     <Item _id={item._id} 
      key={i} // <---- HERE!!
      content={item.content} 
      note={item.note} 
      subItems={item.subItems} 
      insertItem={this.insertItem} />     
  )}
</div>

您的代码存在多个问题:

  1. 您将this.insertItem传递给SubItems(不存在)
  2. 您的this.state.items.splice ,更改this.state.items ,但返回[] 因此,您的新州为[]

尝试这个:

this.state.items.splice(/* your splice argument here */)
this.setState({ items: this.state.items }, () => {
  // this.setState is async! so this is the proper way to check it.
  console.log(this.state.items);
});

要完成您真正想要的,这还远远不够。但是至少,在您修复它之后,您可以看到一些结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM