简体   繁体   English

无法使用React和Redux从自定义组件更新应用程序状态

[英]Cannot update the app state from custom component using React and Redux

I have the following Codesandbox.io : 我有以下Codesandbox.io

https://codesandbox.io/s/qxkq5vvm1q https://codesandbox.io/s/qxkq5vvm1q

which is a basic ReactJS / Redux application. 这是一个基本的ReactJS / Redux应用程序。

The key components here are: 这里的关键组件是:

  • a Select which gets its values something like through this way: Redux (state manager) -> PanelMaterialSize (container) -> Select 一个Select可以通过以下方式获取其值: Redux (state manager) -> PanelMaterialSize (container) -> Select

  • one Updater component which takes care of update the values available on the Select through Redux 一个Updater组件,负责通过Redux更新Select上可用的值

  • Alert button, which when clicked should alert the value stored on the store Alert按钮,单击该按钮应警报存储在store的值

What should happen is: 应该发生的是:

  1. when the user changes an option on the Select , that value should be stored on the store. 当用户更改Select上的选项时,该值应存储在商店中。 This is actually happening properly - OK 这实际上是正常发生的- 好的

  2. if the Select gets its values changed (for example because the Updater component), then it should automatically change the value stored on the store with the value it is showing (something similar as if the user changes the value on it). 如果Select的值发生更改(例如,由于Updater组件),则它应使用其显示的值自动更改存储在商店中的值(类似于用户更改其值)。 Unfortunately this is not happening - The Goal 不幸的是,这没有发生- 目标

Here are some of the codes: 以下是一些代码:

./src/controls/Select/Select.js ./src/controls/Select/Select.js

import React, { Component } from "react";
import "./Select.scss";

class Select extends Component {
  constructor(props) {
    super(props);
    let { name, data, className, ...controlProps } = this.props;
    this.name = name;
    this.data = data;
    this.controlProps = controlProps;
    this.state = {
      [name]: data,
      className
    };
  }

  render() {
    let data = this.state[this.name];
    return (
      <div className="control-select" {...this.controlProps}>
        <div className="custom-dropdown custom-dropdown--grey">
          <select className="custom-dropdown__select custom-dropdown__select--grey">
            {this.props.data.length > 0 &&
              this.props.data.map((elem, index) => {
                return (
                  <option value={elem.value} key={index}>
                    {elem.text}
                  </option>
                );
              })}
          </select>
        </div>
      </div>
    );
  }
}

export default Select;

src/controls/PanelMaterialSize/PanelMaterialSize.js src / controls / PanelMaterialSize / PanelMaterialSize.js

import React, { Component } from "react";
import { connect } from "react-redux";
import "./PanelMaterialSize.scss";
import Select from "../Select/Select";
import { setThemeList, setSelectedTheme } from "../../store/AppConfig/actions";

class PanelMaterialSize extends Component {

  constructor(props) {
    super(props);
    this.state = {
      selection: "",
      options: []
    };
  }

  handleChange = e => {
        let target = e.target;
    let value = target.value;
        this.props.setSelectedTheme(value);
  };

  render() {
    return (
      <div className="partial-designer-panel-material-size">
        <div>
          <div className="label-input">
            <div className="label">THEME</div>
            <div className="input">
              <Select
              name="selection"
              value={this.state.selection}
              data={this.props.themeList}
              style={{ width: "100%" }}
              onChange={this.handleChange}
             />
            </div>
          </div>
        </div>
      </div>
    );
  }
}

const mapStateToProps = appState => {
  return {
    themeList: appState.appConfig.themeList,
    selectedTheme: appState.appConfig.selectedTheme,
  };
};

const mapDispatchToProps = dispatch => {
  return {
    setThemeList: themeList => dispatch(setThemeList(themeList)),
    setSelectedTheme: selectedTheme => dispatch(setSelectedTheme(selectedTheme)),
  };
};

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

Any idea on how to make the point 2 work? 关于如何使第2点起作用的任何想法吗?

If possible, please, provide back your solution on a forked Codesandbox.io . 如果可能,请在分叉的Codesandbox.io上提供您的解决方案。

Thanks! 谢谢!

Updater component is producing new list of themes every 3seconds Updater组件每3秒产生一次新的主题列表

It must also dispatch setSelectedTheme action to update selected theme in application state 它还必须调度setSelectedTheme操作以在应用程序状态下更新所选主题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM