【问题标题】:How to dispatch action in event handler in React & Redux application如何在 React 和 Redux 应用程序的事件处理程序中调度操作
【发布时间】:2019-01-09 08:48:07
【问题描述】:

我的代码在这里:https://stackblitz.com/edit/react-8g3p3l

有2个哑组件

  • insertion_citylist.jsx,代码如下:
  • insertion_shoplist.jsx 使用以下代码:

我预计inseriton_citylist.jsx 中所选城市的更改将触发insertion_shoplist.jsx 中商店列表的更改。所以我的容器组件app.js 包含一个函数findShops,其中调用了动作shoplist(city)

我的容器组件代码app.jsx如下:

import React, { Component } from "react";
import { connect } from "react-redux";
import { citylist, shoplist } from "../actions";
import { bindActionCreators } from "redux";
import CityList from "../components/insertion_citylist";
import ShopList from "../components/insertion_shoplist";

class App extends Component {
  componentDidMount() {
    console.log("mount");
    this.props.citylist();
    this.props.shoplist();
  }

  findShops(city) {
    console.log("findShops:", city);
    this.props.shoplist(city);
  }

  /* renderShops = shops =>
    shops
      ? shops.map(shop => <option key={shop.id} value={shop.name} />)
      : null; */
  render() {
    console.log("render:" + this.props);
    return (
      <div>
        <CityList data={this.props.data} findShops={this.findShops.bind(this)} />
        <ShopList {...this.props} />
        {/* <input list="shop" placeholder="shop" />
        <datalist id="shop">
          {this.renderShops(this.props.shop_data.shops)}
        </datalist> */}
      </div>
    );
  }
}

const mapStateToProps = state => {
  console.log("map state to props:" + state.shops);
  return { data: state.insertion_data }; //Use of spread operator: https://www.youtube.com/watch?v=NCwa_xi0Uuc&t=1721s
  //return { city_data: state.cities, shop_data: state.shops };
};

const mapDispathToProps = dispatch => {
  console.log("map dispatch to props");
  return bindActionCreators({ citylist, shoplist }, dispatch);
};

export default connect(
  mapStateToProps,
  mapDispathToProps
)(App);
当下拉列表中的城市发生变化时,可以成功调用 `findShops`,但似乎 `this.props.shoplist()` 只是调用了 action 而没有调用 *reducer*。 `actions/index.js` 中的操作代码如下所示:
export function citylist() {
  return { type: "CITY_LIST", payload: [{city:"Berlin"}, {city: "Frankfurt"}] };
}

export function shoplist(city) {
  let data = [{name:"original"},{name:"original 2"}];
  if (city === 'Frankfurt') data=[{name:"new"},{name:"new 2"}];
  return {
    type: "SHOP_LIST",
    payload: data
  };
}

问题:当前代码能够触发事件处理程序findShops(),但无法成功更改城市列表state,因此insertion_citylist.jsx 上的城市列表保持不变一直不变。有人可以帮忙吗?

提前致谢!

【问题讨论】:

  • 那么,没有成功,你是什么意思?你有错误吗?我有点好奇你期望findShops 是如何工作的,你只是从传入的道具中得到解构data,但你没有得到findShops,所以你会得到像cannot call something undefined 这样的错误
  • 您可以创建 stackblitz 链接来重现该问题吗?
  • 我没有收到错误。动作函数shoplist(city)在事件处理程序findShops中被成功调用,但是reducer没有工作所以页面上的店铺列表没有改变
  • @Justcode 非常感谢您的建议,我将代码移至 stackblitz :) stackblitz.com/edit/react-8g3p3l
  • 请勿移动代码,请在此处添加重要部分

标签: reactjs ecmascript-6 redux


【解决方案1】:

原来是个很简单的问题

onChange={(e) => props.findShops(e)}

这里你将 e 作为参数传递

findShops(city) {        
    this.props.shoplist(city);
  }

直接使用它,这是无效的,因为你的城市参数中会有事件。

你需要e.target.value

改变

 <select name="city"
 onChange={(e) => props.findShops(e)}>{renderCities(props.data.cities)}</select>

<select name="city"
 onChange={(e) => props.findShops(e.target.value)}>{renderCities(props.data.cities)}</select>

Demo, 记住当你改变值时反应传递一个事件,你需要在读取它时提取值。就像你在 javascript 或 jquery 中所做的那样。

复选框为e.target.checked,输入为e.target.value

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 2015-12-18
    • 2020-02-17
    • 2016-11-28
    • 2021-06-27
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多