Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Can';t使用setState更新对象属性_Javascript_Reactjs - Fatal编程技术网

Javascript Can';t使用setState更新对象属性

Javascript Can';t使用setState更新对象属性,javascript,reactjs,Javascript,Reactjs,我正在创建一个简单的应用程序。我将我的卡片/公告存储在BulletinsList.js中,将单个公告/卡片存储在bulletins.js中 我试图更改第一个公告中的“Hello World”(使用Bulletin.js中的输入,通过单击标题并将其切换为输入)标题,但没有任何效果,所以基本上我无法更新存储在数组中的对象的属性。我正在传递一个object的id,但它不能正常工作。谁能给我一个答案我怎么能做到 BulletinList.js import React, { Component } fr

我正在创建一个简单的应用程序。我将我的卡片/公告存储在BulletinsList.js中,将单个公告/卡片存储在bulletins.js中

我试图更改第一个公告中的“Hello World”(使用Bulletin.js中的输入,通过单击标题并将其切换为输入)标题,但没有任何效果,所以基本上我无法更新存储在数组中的对象的属性。我正在传递一个object的id,但它不能正常工作。谁能给我一个答案我怎么能做到

BulletinList.js

import React, { Component } from 'react';
import Bulletin from '../Bulletin/Bulletin';

class BulletinList extends Component {

    state = {
        bulletin: [
          {
            id: 1,
            title: 'Hello World',
            listOfTasks: ['eat sandwich', 'clean house']
          },
          {
            id: 2,
            title: 'Hello Mars',
            listOfTasks: ['eat spaghetti', 'go to sleep']
          },
        ],
        titleField: '',
        descriptionField: ''
      }


      addEmptyCard = () => {
          this.setState({
              bulletin: [...this.state.bulletin, {id: this.state.bulletin.length + 1, title: '...', listOfTasks: []}]
          })
      }

      captureInput = (event, id) => {
    const specificCard = this.state.bulletin[id - 1];
    this.setState(prevState => ({
        [specificCard]: {                 
            ...prevState.specificCard,    
            title: event.target.value    
        }
    }))
  }




    render() {
        return(
            <div>
                <button onClick={this.addEmptyCard}>+</button>
                {this.state.bulletin.map((element => {
                    return <Bulletin 
                    id={element.id} 
                    title={element.title} 
                    list={element.listOfTasks}
                    captureInput={this.captureInput}/>
                }))}
            </div>
        )
    }
}

export default BulletinList;
import React,{Component}来自'React';
从“../Bulletin/Bulletin”导入公告;
类BulletinList扩展组件{
状态={
公告:[
{
id:1,
标题:“你好,世界”,
任务清单:[“吃三明治”、“打扫房间”]
},
{
id:2,
标题:“你好,火星”,
任务列表:[“吃意大利面”,“睡觉”]
},
],
titleField:“,
descriptionField:“”
}
addEmptyCard=()=>{
这是我的国家({
公告:[…this.state.bulletin,{id:this.state.bulletin.length+1,标题:'…',任务列表:[]]
})
}
captureInput=(事件,id)=>{
const specificCard=此.state.bulletin[id-1];
this.setState(prevState=>({
[特定卡片]:{
…prevState.specificCard,
标题:event.target.value
}
}))
}
render(){
返回(
+
{this.state.bulletin.map((元素=>{
返回
}))}
)
}
}
导出默认公告列表;
Bulletin.js

import React, { useState } from 'react';

const Bulletin = ({ id, title, list, captureInput }) => {

    const [inputOn, setInputOn] = useState(false);

    return(
        <div>
            {!inputOn ? <h1 onClick={() => setInputOn(!inputOn)}>{title}</h1> 
            : 
            <div>
                <input type="text" onChange={(event) => captureInput(event, id)}/>
                <button onClick={() => setInputOn(!inputOn)}>Change title</button>
            </div>}
            {list.map(element => {
                return <p>{element}</p>
            })}
            <input type="text" />
        </div>
    )
}

export default Bulletin;
import React,{useState}来自“React”;
常量公告=({id、标题、列表、captureInput})=>{
const[inputOn,setInputOn]=useState(false);
返回(
{!inputOn?setInputOn(!inputOn)}>{title}
: 
captureInput(事件,id)}/>
setInputOn(!inputOn)}>更改标题
}
{list.map(元素=>{
返回{element}

})} ) } 导出默认公告;
captureInput
中,您不会覆盖
公告
属性,而是使用对象作为索引创建一个新属性。解决此问题的正确方法之一是:

captureInput = (event, id) => {
    const newBulletin = [...this.state.bulletin];
    newBulletin[id - 1].title = event.target.value;
    this.setState({
            bulletin: newBulletin
    });
}
我在这里使用扩展语法创建一个新数组,然后在给定位置覆盖元素的
title
属性

另外,您将元素的
id
传递给公告组件,然后将其用作索引。它现在可以工作,因为标识符是有序的,但最好通过迭代数组来找到真正的索引:

captureInput = (event, id) => {
    const elemIndex = this.state.bulletin.findIndex(elem => elem.id === id);
    const newBulletin = [...this.state.bulletin];
    newBulletin[elemIndex].title = event.target.value;
    this.setState({
            bulletin: newBulletin
    });
}

这样,您就可以在不破坏应用程序的情况下删除项目。

谢谢!我还有一个问题,你知道为什么这个函数不能正常工作吗?它涉及到删除特定任务,如“吃意大利面”
deleteTask=(id)=>{const specificblutin=this.state.bulletin[id-1].listOfTasks;this.setState({specificblutin:specificblutin.splice(id-1,1),})
同样的原因-您正在状态中创建“specificBulletin”属性。复制我上面发布的代码,但不要覆盖
标题
筛选出要删除的任务:
newBulletin[elemIndex].listoftask=newBulletin[elemIndex].listoftask.filter(element=>element.id!==id)
。它将创建一个新数组,而不包含具有给定
id
的元素。黄金法则是在更新状态时始终提供新引用(不变性)。