javascript - React.js 不在状态更新时重新渲染应用程序

标签 javascript reactjs ecmascript-6

我正在研究基于 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>

关于javascript - React.js 不在状态更新时重新渲染应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42038613/

相关文章:

javascript - 使用 useState 从数组中删除最后一项

javascript - 在不同组件中重置 Tic Tac Toe 的方法

javascript - 在按钮单击事件上渲染 React 组件

javascript - 无法使用 axios 设置状态

javascript - 目录导入索引文件无法正常工作

javascript - 使用键盘命令显示 div

javascript - 使用 ||运营商通知

javascript - 找不到此 JavaScript 代码中的错误所在。对 'class'语法不太熟悉

javascript - 为什么在 Next.js 中未定义解构的环境变量?

node.js - Sequelize [ES6] 分离文件循环引用