【问题标题】:React Redux putting Array into Store Only Updates on first ChangeReact Redux 将 Array 放入 Store Only Updates on first Change
【发布时间】:2018-03-25 03:24:46
【问题描述】:

我是 React 和 Redux 的新手,所以我可能在这里犯了一个新手错误。

我在页面上有一个可见的值数组。然后,用户可以更改一个值,该值被分派到商店、侦听,然后页面被更新。我发现的只是第一次听的作品。 (例如:只有第一个更改被 react-redux 监听器拾取并在页面上更新。

注意:这是我第一次在 React/Redux 中使用数组 - 布尔值和字符串对我来说很好用。

组件:

import React from 'react'
import { Card } from 'material-ui'
import Close from 'material-ui-icons/Close'
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import {
    setHfcLiveModemPerfChartComponentOptionsStatus,
    setHfcLiveModemPerfChartComponentThresholdStatus
} from "../actions"



class HfcLiveModemPerfChartOptions extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            popUpThreshold: [-10000, 25, 25, 40, 40, 60, 60, 80, 80, 10000]
        }
    }


    handleCloseOptions() {
        this.props.HfcLiveModemOptionsClose();
    }


    handleThresholdChange(type, event) {
        this.state.popUpThreshold[type] = event.target.value;
        this.props.HfcLiveModemThresholdChange(this.state.popUpThreshold);
    }


    render() {

        console.log('plz rerender now...');

        if(this.props.contentRender) {      // Conditional Rendering

            console.dir(this.state.popUpThreshold);

            return (
                <div>
                    <Card id="HfcLiveModemPerfChartOptions" className="cardOptionsContainer">
                        <h3 id="optionsTitle">Component Options</h3>
                        <Close
                            className="optionsClose"
                            onClick={this.handleCloseOptions.bind(this)}
                        />

                        <h4 id="optionsSubTitle">Admin Threshold ColorBands</h4>
                        <table>
                            <tbody>
                                <tr>
                                    <td><div className="colorBox colorBoxRed"></div></td>
                                    <td className="colorBandName">Red Low</td>
                                    <td>
                                        <input
                                            type="number"
                                            placeholder="-10000"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[0]}
                                            onChange={this.handleThresholdChange.bind(this, 0)}
                                        />
                                    </td>
                                    <td>
                                        <input
                                            type="number"
                                            placeholder="-15"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[1]}
                                            onChange={this.handleThresholdChange.bind(this, 1)}
                                        />
                                    </td>
                                </tr>
                                <tr>
                                    <td><div className="colorBox colorBoxOrange"></div></td>
                                    <td className="colorBandName">Orange Low</td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="-15"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[2]}
                                            onChange={this.handleThresholdChange.bind(this, 2)}
                                        />
                                    </td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="0"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[3]}
                                            onChange={this.handleThresholdChange.bind(this, 3)}
                                        />
                                    </td>
                                </tr>
                                <tr>
                                    <td><div className="colorBox colorBoxGreen"></div></td>
                                    <td className="colorBandName">Green</td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="0"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[4]}
                                            onChange={this.handleThresholdChange.bind(this, 4)}
                                        />
                                    </td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="10"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[5]}
                                            onChange={this.handleThresholdChange.bind(this, 5)}
                                        />
                                    </td>
                                </tr>
                                <tr>
                                    <td><div className="colorBox colorBoxOrange"></div></td>
                                    <td className="colorBandName">Orange High</td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="10"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[6]}
                                            onChange={this.handleThresholdChange.bind(this, 6)}
                                        />
                                    </td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="15"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[7]}
                                            onChange={this.handleThresholdChange.bind(this, 7)}
                                        />
                                    </td>
                                </tr>
                                <tr>
                                    <td><div className="colorBox colorBoxRed"></div></td>
                                    <td className="colorBandName">Red High</td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="15"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[8]}
                                            onChange={this.handleThresholdChange.bind(this, 8)}
                                        />
                                    </td>
                                    <td>
                                        <input
                                            type="text"
                                            placeholder="10000"
                                            className="thresholdValue"
                                            value={this.state.popUpThreshold[9]}
                                            onChange={this.handleThresholdChange.bind(this, 9)}
                                        />
                                    </td>
                                </tr>
                            </tbody>
                        </table>

                    </Card>
                </div>
            )
        }else{return false}
    }
}



HfcLiveModemPerfChartOptions.propTypes = {
    contentRender: PropTypes.bool,
    popUpThreshold: PropTypes.array

};

const mapStateToProps = (state) => {
    return {
        contentRender: state.setHfcLiveModemPerfChartComponentOptionsStatus.setHfcLiveModemPerfChartComponentOptionsStatusState,
        popUpThreshold: state.setHfcLiveModemPerfChartComponentThresholdStatus.setHfcLiveModemPerfChartComponentThresholdStatusState
    }
}

const mapDispatchToProps = (Dispatch) => {
    return({
        HfcLiveModemOptionsClose: () => Dispatch(setHfcLiveModemPerfChartComponentOptionsStatus),
        HfcLiveModemThresholdChange: (value) => Dispatch(setHfcLiveModemPerfChartComponentThresholdStatus(value))
    })
}

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

动作/主动创建者:

export const HFC_LIVE_MODEM_PERF_CHART_COMPONENT_THRESHOLD_STATUS = 'HFC_LIVE_MODEM_PERF_CHART_COMPONENT_THRESHOLD_STATUS'

export function setHfcLiveModemPerfChartComponentThresholdStatus(value) {
    return {
        type: 'HFC_LIVE_MODEM_PERF_CHART_COMPONENT_THRESHOLD_STATUS',
        value
    }
}

减速机:

// HFC Live Modem Performance Chart Threshold Reducer
const setHfcLiveModemPerfChartComponentThresholdStatusInitState = {setHfcLiveModemPerfChartComponentThresholdStatusState: []};
const setHfcLiveModemPerfChartComponentThresholdStatus = (state = setHfcLiveModemPerfChartComponentThresholdStatusInitState, action) => {
    switch (action.type) {
        case HFC_LIVE_MODEM_PERF_CHART_COMPONENT_THRESHOLD_STATUS:
            let newState = {};
            newState['setHfcLiveModemPerfChartComponentThresholdStatusState'] = action.value;
            return Object.assign({}, state, newState);
        default:
            return state;
    }
}

// Combine & Export Reducers
export default combineReducers({
    setHfcLiveModemPerfChartComponentThresholdStatus
})

DOM 元素图像:

Redux 视图:

这可能与我在 Redux 中存储数组的方式有关。

可能我应该在存储之前对数组进行字符串化?

** 更新: 调度/侦听器第一次工作,但此后值在 Redux 中更新,但侦听器没有获取更改,因此页面没有更新..

非常感谢!

【问题讨论】:

  • 你不应该直接改变状态。您需要使用setState,但在您的情况下,您根本不需要将数组存储在 React 状态。
  • 你能解释一下我是如何直接改变状态的吗?当您说不在 React 中存储数组时,您的意思是存储 10 个单独的值吗?注意:我需要 Redux 中的值,因为其他组件在更改时会监听/需要这些数字。
  • 这:this.state.popUpThreshold[type] = event.target.value; 不应该这样做。见stackoverflow.com/questions/26253351/…
  • 好电话-我错过了一些...我会更新但不确定是否能解决问题-谢谢您的帮助:)

标签: arrays reactjs redux


【解决方案1】:

问题是 React 每次只对props 进行浅层检查。你的 Redux 存储形状必须比对象内部的数组更扁平。尝试将数组存储在 Redux 存储中。并仅使用更改值的索引和值而不是整个数组来调度操作。然后执行以下操作:

handleThresholdChange(type, event) {
    this.state.popUpThreshold[type] = event.target.value;
    this.props.HfcLiveModemThresholdChange(type, event.target.value);
}

export function setHfcLiveModemPerfChartComponentThresholdStatus(index, value) {
    return {
        type: 'HFC_LIVE_MODEM_PERF_CHART_COMPONENT_THRESHOLD_STATUS',
        index,
        value
    }
}

const setHfcLiveModemPerfChartComponentThresholdStatusInitState = [];

const setHfcLiveModemPerfChartComponentThresholdStatus = (state = setHfcLiveModemPerfChartComponentThresholdStatusInitState, action) => {
    switch (action.type) {
        case HFC_LIVE_MODEM_PERF_CHART_COMPONENT_THRESHOLD_STATUS:
          return Object.assign(
            {},
            state,
            { [action.index]: action.value }
          );
        default:
            return state;
    }
}

如果它不起作用,请告诉我。

【讨论】:

  • 嘿-感谢您的来信。所以你说分开存储每个值?这是为了避免嵌套结构,如 React/Redux 不检查的数组 - 平面问题......
  • 不单独存储每个值。 Redux 存储将包含一个数组而不是对象内部的数组。我说过,当一个值改变时,你需要dispatch一个动作,只需要改变的值而不是整个数组......这更有意义。
  • 是的,这是有道理的——我需要做更多的测试(一如既往),但我现在理解得更好了——谢谢你的来信:)
猜你喜欢
  • 2015-12-21
  • 2022-12-02
  • 2019-08-10
  • 2021-02-01
  • 2022-08-08
  • 2022-12-01
  • 2020-07-31
  • 2020-11-26
  • 1970-01-01
相关资源
最近更新 更多