【问题标题】:Cannot pass data between components in React/Redux无法在 React/Redux 中的组件之间传递数据
【发布时间】:2020-06-26 00:29:50
【问题描述】:

我是 React 新手,我正在尝试构建一个应用程序,将足球运动员分成两支球队,并且在将数据从一个组件传递到另一个组件时遇到困难。我已经安装了 redux 和 react-redux。

我的问题是,一旦输入了 10 个名称(我称之为 numbersReached),提交 addPlayers 表单的按钮应该被禁用,因此无法提交更多玩家。

我尝试将状态值 numbersReached 传递到我的 AddPlayers 组件中,但它没有被正确导入 - 它在 console.log 中显示为 undefined

到目前为止我的代码:

'initialState.js'

export const initialState = {
  playersList: [],
  shuffledList: [],
  teamA: [],
  teamB: [],
  numbersReached: false
};

export default initialState;

'src\components\NumbersReached\index.js':

import { connect } from "react-redux";
import NumbersReached from "./NumbersReached";

const mapStateToProps = (state) => {
  return {
    ...state,
    numbersReached: state.playersList.length >= 10 // Once state.playersList.length>=10 numbersReached should = true. (10 is for five-a-side)
  };
};

export default connect(mapStateToProps)(NumbersReached);

src\components\NumbersReached\NumbersReached.js:

import React from "react";

const NumbersReached = ({ numbersReached }) => (
  <div>
    {numbersReached ? "Numbers Reached" : null}
  </div>
);

export default NumbersReached;

'src\components\AddPlayer\index.js':

import { connect } from "react-redux";
import AddPlayer from "./AddPlayer";
import { addPlayer } from "../../data/actions";

const mapStateToProps = (state) => {
  return {
    playerName: state.playerName,
    numbersReached: state.numbersReached
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    handleSubmit: (data) => dispatch(addPlayer(data)),
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(AddPlayer);

'src\components\AddPlayer\AddPlayer.js'

import React, { Component } from 'react';

class AddPlayer extends Component {

  constructor(props) {
    super(props);

    this.state = {
      playerName: props.playerName,
      numbersReached: props.numbersReached
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);

  };

  handleChange(e) {
    this.setState({ playerName: e.currentTarget.value });
  }

  handleSubmit(e) {
    e.preventDefault();
    this.props.handleSubmit({ ...this.state });
  }


  render() {

    return (
      <React.Fragment>
        <form className="entry-form" onSubmit={this.handleSubmit}>
          <input
            placeholder="Enter a player's name"
            className="player-input"
            type="text"
            onChange={this.handleChange}
          />
          <button
            type="submit"
            className="player-submit"
            disabled={this.state.numbersReached}  // Does not disable the button as this.state.numbersReached is undefined
          >
            Add a player
          </button>
        </form>

      </React.Fragment>
    )

  }
};

export default AddPlayer;

非常感谢您的帮助!

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    您可能遇到的问题是您实际上并没有在 Redux 存储中使用 numbersReached 的值。相反,您在 AddPlayer 组件的状态中使用了 numbersReached 变量。

    <button
      type="submit"
      className="player-submit"
      disabled={this.state.numbersReached}
    >
    

    要使用您在mapStateToProps 中定义的numbersReached您应该访问this.props.numbersReached 而不是this.state.numbersReached。当 action addPlayer 被调度并且 Redux 存储发生变化时,你从 Redux 继承的 props 将自动更新。

    但是,除非您在组件中的任何位置调用 setState,否则您的 this.state.numbersReached 的值不会改变。现在,您只是在构造函数上初始化该值:

    class AddPlayer extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          playerName: props.playerName,
          numbersReached: props.numbersReached
        };
      };
    }
    

    执行此操作时,您将在组件的状态中创建一个新的 numbersReached 变量,其值与构建组件时 Redux 存储中的 numbersReached 属性具有的值相同。由于构造函数运行时它没有值,所以this.state.numbersReachedundefined

    执行numbersReached: props.numbersReached 并不要求您对该属性进行所有更改;它只是将 numbersReached 分配给 props.numbersReached 最初的值。这就是为什么,无论您添加多少玩家,即使玩家已成功添加到您的商店,它仍将是 undefined。 p>

    【讨论】:

      【解决方案2】:

      您正在AddPlayer 状态复制 redux 状态。重复状态是不好的做法,应该避免。其次,它们是不同的状态,redux'state 和 react 组件的 state。因为它是this.state.numbersReached 在安装时收到第一个值,但以后不会更新。

      在你的状态playerName: props.playerName 也很奇怪。首先,你的 redux 中没有一个名为 playerName 的状态。其次,最重要的是,它是一个创建玩家并添加到您的playersList 的组件。您最好将该状态初始化为空字符串。

      顺便说一句,我对您的组件进行了一些重构以减少代码。如果您将函数声明为箭头函数,则不需要在构造函数中绑定它们。并且您不再需要在构造函数中声明您的状态。但是,如果您想保持原件以保持一致性,或者个人喜好继续,那也可以:)。

      毕竟,您的组件看起来像:

      import React, { Component } from 'react';
      
      class AddPlayer extends Component {
      
        state = {
          playerName: ''
        };
      
      
        handleChange = (e) => {
          this.setState({ playerName: e.currentTarget.value });
        }
      
        handleSubmit = (e) => {
          e.preventDefault();
          this.props.handleSubmit({ ...this.state });
        }
      
      
        render() {
      
          return (
            <React.Fragment>
              <form className="entry-form" onSubmit={this.handleSubmit}>
                <input
                  placeholder="Enter a player's name"
                  className="player-input"
                  type="text"
                  onChange={this.handleChange}
                />
                <button
                  type="submit"
                  className="player-submit"
                  disabled={this.props.numbersReached}
                >
                  Add a player
                </button>
              </form>
      
            </React.Fragment>
          )
      
        }
      };
      
      export default AddPlayer;
      

      最后一点,您有 numbersReached 状态,但在您的 mapStateToProps 中,您基于自定义函数设置,而不是您的 numbersReached 状态。

      如果你想在你的 redux 状态中保持 numbersReached 状态,你应该在你的 reducer 处处理该逻辑 state.playersList.length &gt;= 10 以便在那里正确更新,而不是在你的 mapStateToProps 处。尽管您可以完全从您的 redux 状态中删除 numbersReached,因为它是从您所在州的其他部分派生的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-15
        • 1970-01-01
        • 1970-01-01
        • 2022-01-20
        • 2019-01-04
        • 1970-01-01
        • 2022-01-21
        相关资源
        最近更新 更多