【问题标题】:Unable to get a variable into state using setState onClick无法使用 setState onClick 使变量进入状态
【发布时间】:2016-05-20 03:08:11
【问题描述】:

做一个 React 项目并不断遇到类似的问题。在单击时使用 setState 使变量进入状态时遇到问题。在这种情况下,当单击相应的按钮时,我无法将我的播放器对象传递为 ActivePlayer 状态。但是,我可以将其设置为变量,但在应用程序中的其他情况下,我需要将其设置为状态,这似乎是最直接的示例。

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import AdminSubNav from 'components/admin-subnav';
import { getPlayers } from 'api/index.js';
import { archivePlayer } from 'api/index.js';
let players = [];
let activePlayer = {};

export default class PlayerView extends React.Component {
    constructor(props) {
    super(props);
        this.state = {
          players: [],
          activePlayer: {},
          player: {}
        }
    }

    componentWillMount() {
          getPlayers().then((response) => {
                players = response.data;
                console.log(players);
                this.setState({ players:players });
            });
    }

    onClick(player) {
        // let activePlayer = player;
        this.setState({
            activePlayer:player
        });
        console.log(activePlayer);
        console.log(this.state);
        // archivePlayer(this.props.params.id)
        //     .then(() => {
        //         this.context.router.push('/player');
        //     });
    }

    renderPlayers() {
        return players.map((player) => {
            return (
                <tr key={player.id}>
                  <td>{player.NameLast}, {player.NameFirst}</td>
                  <td>{player.teamName}</td>
                  <td><Link to='/'><i className='material-icons small'>create</i></Link></td>
                  <td><button onClick={this.onClick.bind(this, player)}><i className='material-icons small'>delete</i></button></td>
                </tr>
            );
        });
    }


  render () {

    return (
        <div>
            {/*<AdminSubNav title="Player View" route="/team/add"/>*/}
            <div className="admin-table-wrapper">
                <h3>PLAYERS</h3>
                <Link to="/player/add">ADD PLAYER</Link>
                <table className="admin-table">
                <col className="at-col1"/>
                <col className="at-col2"/>
                <col className="at-col3"/>
                <col className="at-col4"/>
                    <thead>
                         <tr>
                             <th data-field='id'>Player Name</th>
                             <th data-field='name'>Team</th>
                             <th data-field='price'>Edit</th>
                             <th data-field='price'>Archive</th>
                         </tr>
                    </thead>
                    <tbody>
                    {this.renderPlayers()}
                    </tbody>
                </table>
            </div>
        </div>
    );
  }
}

【问题讨论】:

  • setState 文档说明了这一点,'setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。'

标签: javascript reactjs state setstate


【解决方案1】:

您确定这不起作用,还是 console.logs 只是不起作用? setState 是一个异步函数,所以如果你设置了状态,然后在它不存在后立即查找它。尝试使用setState 中的回调,如下所示:

this.setState({ /* state */ },() => {
   // console.log and check stuff
   // Also do any other function calls that you need to to explicitly   after the state has been updated
})

不确定这是否能解决问题,但记住 setState 的异步特性很重要!

【讨论】:

  • 啊,是的,确实正确记录了状态。谢谢你,你是男人!!也就是说,在我使用回调 setState 的另一个组件中,某些组件并没有按照我认为的方式重新渲染。我有一个在 componentWillMount 上调用的 API,然后是一个由日期选择器调用的 OnChange 函数,我想用新数据调用 API。 componentWillMount 只能调用一次吗?如果是这样,我是否直接在 handleChange 函数中进行新的 API 调用?另外,这应该是一个带有代码示例的新问题吧?再次感谢您!
  • 很好,很高兴我能帮上忙!如果您不介意将其标记为已接受的答案,我将不胜感激;) 是的,您可以提出另一个问题并将链接作为评论发布在这里,我会去看看!
【解决方案2】:

试试这个

{this.renderPlayers.bind(this)()}

或者你也可以把它放在构造函数中

constructor(props) {
    super(props);
    this.state = {
      players: [],
      activePlayer: {},
      player: {}
    }
    this.renderPlayers = this.renderPlayers.bind(this);
}

【讨论】:

  • 避免在 React 组件中使用 classes 的众多原因之一。坚持使用 React.createClass({}) :)
【解决方案3】:

在您的 renderPlayers 函数中,您正在调用

players.map((player) =>

其中将引用顶级玩家数组。我会试试的

this.state.players.map((player) =>

在您的 renderPlayers 函数中

我也会尝试在组件 api 上的 getInitialState 中设置您的状态

getInitialState() {
  return {
          players: [],
          activePlayer: {},
          player: {}
         }
}

【讨论】:

  • players 是这个家伙代码中的一个全局数组,工作正常:(
【解决方案4】:

可能问题出在 onClick 竞价中。

我遇到了同样的问题,并通过 onClick 处理程序解决了它,试试这个:

constructor(props) {
    super(props);
        this.state = {
          players: [],
          activePlayer: {},
          player: {}
        }
       this.onClick = this.onClick.bind(this);
    }

您可以在 React 文档中看到它:https://reactjs.org/docs/handling-events.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 2019-07-19
    • 1970-01-01
    • 2020-07-07
    相关资源
    最近更新 更多