Reactjs 为什么我不能使用方法setState()来数组元素

Reactjs 为什么我不能使用方法setState()来数组元素,reactjs,Reactjs,如何更改数组中每个对象的展开状态列表。我想更改eachClose()函数中的状态。每次尝试更改数组列表中对象的状态时,我都会从React编译器中得到该错误: 类型错误:item.setState不是函数 class Item extends React.Component{ constructor(props){ super(props); this.state = { expanded: fals

如何更改数组中每个对象的
展开状态
列表
。我想更改
eachClose()函数中的状态。每次尝试更改数组
列表中对象的状态时,我都会从React编译器中得到该错误:

类型错误:item.setState不是函数

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

            this.state = {
                expanded: false,
            };
}

class ItemList extends React.Component{
    constructor(props){
        super(props);

        this.state = { 
            list: [ 
                <Item />,
                <Item />,
                <Item />,
                <Item />,
                <Item />,
            ]
        };
    }
    

    eachClose = () => {
        this.state.list.map ((item, i) => item.setState({expanded: false}))
    }

    render(){
        return(
            <div className="users">
                {this.state.list.map ((item, i) => <Item id={i} key={i} />)}
                <button onClick={this.eachClose}>Click</button>
            </div>
        );
    }
}
类项扩展React.Component{
建造师(道具){
超级(道具);
此.state={
扩展:错,
};
}
类ItemList扩展了React.Component{
建造师(道具){
超级(道具);
this.state={
名单:[
,
,
,
,
,
]
};
}
每个糖=()=>{
this.state.list.map((item,i)=>item.setState({expanded:false}))
}
render(){
返回(
{this.state.list.map((项,i)=>)}
点击
);
}
}

如上所述,在您的情况下,
不是实际元素的实例。此外,将元素保持在状态是一种反模式

相反,您需要保留
列表
状态中每个元素的信息,并使用列表中的信息呈现项目。如下所示:

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

            this.state = {
                expanded: props.expanded, // idea is to get expanded state from props
            };
     //.... rest of component. btw, probably you do not need state here at all
}    

class ItemList extends React.Component{
        constructor(props){
            super(props);
    
            this.state = { // keep data for items, not items themself
                list: [ 
                    { expanded: true },
                    { expanded: true },
                    { expanded: true },
                    { expanded: true },
                    { expanded: true }
                ]
            };
        }
        
    
        eachClose = () => {
            const newList = this.state.list.map((item) => {
              return { ...item, expanded: false };
            });
            this.setState({ list: newList });
        }
    
        render(){
            // now render list according to info in state
            return(
                <div className="users">
                    {this.state.list.map((item, i) => <Item id={i} key={i} expanded={item.expanded} />)}
                    <button onClick={() => this.eachClose()}>Click</button>
                </div>
            );
        }
    }
类项扩展React.Component{
建造师(道具){
超级(道具);
此.state={
expanded:props.expanded,//思想是从props获取扩展状态
};
//…组件的其余部分。顺便说一句,这里可能根本不需要状态
}    
类ItemList扩展了React.Component{
建造师(道具){
超级(道具);
this.state={//保留项目的数据,而不是项目本身
名单:[
{扩展:true},
{扩展:true},
{扩展:true},
{扩展:true},
{扩展:真}
]
};
}
每个糖=()=>{
const newList=this.state.list.map((项)=>{
返回{…项,展开:false};
});
this.setState({list:newList});
}
render(){
//现在根据状态中的信息呈现列表
返回(
{this.state.list.map((项,i)=>)}
this.eachClose()}>单击
);
}
}
这是给你的密码笔:
item
实际上不是
item
的实例,它是一个React元素,它只是需要呈现内容的描述符。状态是组件内部的东西,不会“从外部”更改。看起来您可能希望将
扩展的
作为道具传递。同时将React元素存储在状态中是不寻常的。fwiw,
是一个对象,这样您就可以在
映射
中对其进行变异。如果执行
返回{…项,扩展:false}之类的操作,效果会更好
或者因为它只是这个项目的一个键
返回{expanded:false}
@buzatto,谢谢,很好的一点!更新了答案。点击按钮后,道具不会改变,按钮也不会更新。@АССССцСццццц,是的,这是因为上下文错误(
这个
)绑定在
onClick
中。我已经用正确的命令更新了答案:
onClick={()=>this.eachClose()}
请尝试。简而言之,如果没有arrow函数包装器,
eachClose
函数中的
将绑定到按钮
而不是我们的组件上下文。使用arrow函数作为包装器,我们将其绑定到适当的上下文,我们可以使用
onClick={this.eachClose.bind>实现相同的行为(此)}
但使用箭头函数更短,可读性更高。
列表
具有扩展值​​已正确更新,但其值​​未传递给道具。对于
,道具始终为