【问题标题】:How to setState from within a mapped item within React component如何从 React 组件内的映射项中设置状态
【发布时间】:2019-05-31 02:25:55
【问题描述】:

我正在尝试更改组件的状态,该组件是来自 json 文件的对象映射数组的一部分。我只想更改包含单击按钮的项目,而不更改其他项目。

我一直在尝试使用 onClick 设置属性 (projectID),虽然我可以让它切换一个状态元素(扩展或未扩展),但它对所有返回的结果都执行此操作。所以我一直在尝试获取 projectId (在数据中设置)并使用它来设置条件。但我似乎无法让 projectId 通过点击进行更新。我简单地玩了一下上下文,但我认为我缺少一些更简单的东西。我已经在 onClick(如图所示)和 onViewChange 中尝试过,但这似乎不起作用,因为我无法从映射项外部访问 item.id。

我正在使用基于从几个级别传递下来的道具的条件来设置类别,仅显示我想要的对象。那部分似乎正在工作。所以我删除了我的展开状态,因为这里的问题没有必要。

 import React from 'react';
 import projects from '../data/projects.json';

 class ProjectCard extends React.Component {

  constructor(props) {
    super(props);
    this.state={
        projects,
        expanded: false,
        projectId: -1
    }
  }

  onViewChange = (e) => {
    this.setState({
        expanded: !this.state.expanded
    });
    console.log(this.state.projectId)
  };

  render() {
    return (
        <React.Fragment>
        {this.state.projects.map((item) => {
            if (!this.state.expanded && item.category === this.props.category) { 
                return (
                        <div key={item.id} className="project-card">
                            <div className="previewImg" style={{backgroundImage: `url(${item.previewImg}` }} ></div>
                            <div className="copy">
                                <h2>{item.title}</h2>
                                <p>{item.quickDesc}</p>
                            </div>
                            <div className="footer">
                            {item.tools.map((tool) => {
                                return ( 
                                    <div key={tool} className="tools" style={{backgroundImage: `url(${tool}` }}></div>
                                );
                            }
                            )}
                                <button onClick={() => this.onViewChange({projectId: item.id})} className="btn float-right"><i className="fas fa-play"></i></button>
                            </div>
                        </div> 
                        );
                    }
            }

        )}
        </React.Fragment>
    );
  };
};

 export default ProjectCard;

我设置了一个控制台日志来告诉我 projectId 是否发生了变化,并且它总是作为我的默认值 (-1) 返回。粘贴的版本是唯一不会在未定义的值/对象方面引发错误的版本,但仍然没有任何变化。如果我可以根据单击按钮中的 item.id 来更改 projectId,我想我可以找出条件并从那里获取它。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您实际上并没有在单击处理程序中使用新的projectId 设置状态。第一步只是简单地将项目的 ID 传递给点击处理程序,而不是对象:

    onClick={() => this.onViewChange(item.id)}
    

    第二部分是在您的点击处理程序中实际使用该参数:

    onViewChange = (id) => {
        this.setState({
            expanded: !this.state.expanded,
            projectId: id
        });
     };
    

    另外,setState() 是异步的,所以你不能做你所做的事情,console.log 你的状态在下一行,并期望它已经改变。在渲染函数顶部记录状态以查看它何时更改(在状态/道具更改后,调用渲染)。或者另一种选择是使用setState 的可选第二个参数,这是一个以新状态执行的回调:

    this.setState({id: 5}, () => console.log(this.state.id)) <-- id will be 5
    

    【讨论】:

    • 效果很好,谢谢!我记得尝试过 this.onViewChange(item.id) - 以及其他几十个“如果我这样做会怎样”的猜测,但我认为我错过了将 id 传递回 onViewChange 而不是传递事件的那部分。 60 小时的培训视频,这是我尝试的第一个非教程。非常感谢您的帮助!
    • @cebronix 不用担心 :) 顺便说一句,如果你也想通过这个活动,你可以这样:onClick={(event) =&gt; someFunction(event, ...otherArgs)}
    猜你喜欢
    • 2019-05-05
    • 2018-09-19
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多